diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..39697f41 --- /dev/null +++ b/.clang-format @@ -0,0 +1,138 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 240 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +# InsertNewlineAtEOF: true # clang 16 which is not widely installed +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +... + diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml new file mode 100644 index 00000000..d8546509 --- /dev/null +++ b/.github/workflows/clang-format-check.yml @@ -0,0 +1,21 @@ +name: clang-format Check +on: [push, pull_request] +jobs: + formatting-check: + name: Formatting Check + runs-on: ubuntu-latest + strategy: + matrix: + path: + - check: 'src' + exclude: '(Globals.c|GlobalsBrogue.c|GlobalsRapidBrogue.c)' + + steps: + - uses: actions/checkout@v3 + - name: Run clang-format style check for C/C++/Protobuf programs. + uses: jidicula/clang-format-action@v4.11.0 + with: + clang-format-version: '10' + check-path: ${{ matrix.path['check'] }} + exclude-regex: ${{ matrix.path['exclude'] }} + fallback-style: 'Mozilla' # optional \ No newline at end of file diff --git a/Makefile b/Makefile index a942041a..6646fb61 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ include config.mk +FORMATTER_EXCLUSION_LIST := "src/brogue/Globals.c" "src/variants/GlobalsRapidBrogue.c" "src/variants/GlobalsBrogue.c" + cflags := -Isrc/brogue -Isrc/platform -Isrc/variants -std=c99 \ -Wall -Wpedantic -Werror=implicit -Wno-parentheses -Wno-unused-result \ -Wformat -Werror=format-security -Wformat-overflow=0 @@ -78,6 +80,9 @@ include make/*.mk clean: $(warning 'make clean' is no longer needed in many situations, so is not supported. Use 'make -B' to force rebuild something.) +format: + @./formatter.sh src $(FORMATTER_EXCLUSION_LIST) + escape = $(subst ','\'',$(1)) vars: mkdir -p vars @@ -86,5 +91,6 @@ vars/%: vars FORCE @echo '$(call escape,$($*))' > vars/$*.tmp @if cmp --quiet vars/$*.tmp vars/$*; then :; else cp vars/$*.tmp vars/$*; fi +.PHONY: format FORCE: diff --git a/formatter.sh b/formatter.sh new file mode 100755 index 00000000..3befe8c4 --- /dev/null +++ b/formatter.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Function to recursively find source files and run clang-format +function format_source_files() { + local root_dir="$1" + local exclude_list=("$@") + + find "$root_dir" -type f \( -name "*.c" -o -name "*.cpp" -o -name "*.h" \) | while read -r file; do + # Check if the file should be excluded + if [[ ! " ${exclude_list[@]} " =~ " ${file} " ]]; then + echo "Formatting: $file" + clang-format -i "$file" + # sed command to ensure files end with a newline + sed -i -e '$!b' -e '/^$/!a\' "$file" + else + echo "Excluding: $file" + fi + done +} + +# Check if the correct number of arguments is provided +if [ "$#" -lt 2 ]; then + echo "Usage: $0 ... " + exit 1 +fi + +directory_root="$1" +shift # Remove the first argument (directory_root) from the arguments list + +# Call the format_source_files function with the provided arguments +format_source_files "$directory_root" "$@" diff --git a/src/brogue/Architect.c b/src/brogue/Architect.c index cf4a9b1e..e8799261 100644 --- a/src/brogue/Architect.c +++ b/src/brogue/Architect.c @@ -30,7 +30,7 @@ short topBlobMinX, topBlobMinY, blobWidth, blobHeight; #ifdef BROGUE_ASSERTS // otherwise handled as a macro in rogue.h boolean cellHasTerrainFlag(short x, short y, unsigned long flagMask) { assert(coordinatesAreInMap(x, y)); - return ((flagMask) & terrainFlags((x), (y)) ? true : false); + return ((flagMask)&terrainFlags((x), (y)) ? true : false); } #endif @@ -46,12 +46,11 @@ boolean checkLoopiness(short x, short y) { for (sdir = 0; sdir < DIRECTION_COUNT; sdir++) { newX = x + cDirs[sdir][0]; newY = y + cDirs[sdir][1]; - if (!coordinatesAreInMap(newX, newY) - || !(pmap[newX][newY].flags & IN_LOOP)) { + if (!coordinatesAreInMap(newX, newY) || !(pmap[newX][newY].flags & IN_LOOP)) { break; } } - if (sdir == 8) { // no unloopy neighbors + if (sdir == 8) { // no unloopy neighbors return false; // leave cell loopy } @@ -100,9 +99,7 @@ boolean checkLoopiness(short x, short y) { void auditLoop(short x, short y, char grid[DCOLS][DROWS]) { short dir, newX, newY; - if (coordinatesAreInMap(x, y) - && !grid[x][y] - && !(pmap[x][y].flags & IN_LOOP)) { + if (coordinatesAreInMap(x, y) && !grid[x][y] && !(pmap[x][y].flags & IN_LOOP)) { grid[x][y] = true; for (dir = 0; dir < DIRECTION_COUNT; dir++) { @@ -115,8 +112,8 @@ void auditLoop(short x, short y, char grid[DCOLS][DROWS]) { } } -// Assumes it is called with respect to a passable (startX, startY), and that the same is not already included in results. -// Returns 10000 if the area included an area machine. +// Assumes it is called with respect to a passable (startX, startY), and that the same is not already included in +// results. Returns 10000 if the area included an area machine. short floodFillCount(char results[DCOLS][DROWS], char passMap[DCOLS][DROWS], short startX, short startY) { short dir, newX, newY, count; @@ -128,12 +125,10 @@ short floodFillCount(char results[DCOLS][DROWS], char passMap[DCOLS][DROWS], sho results[startX][startY] = true; - for(dir=0; dir<4; dir++) { + for (dir = 0; dir < 4; dir++) { newX = startX + nbDirs[dir][0]; newY = startY + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && passMap[newX][newY] - && !results[newX][newY]) { + if (coordinatesAreInMap(newX, newY) && passMap[newX][newY] && !results[newX][newY]) { count += floodFillCount(results, passMap, newX, newY); } @@ -160,8 +155,7 @@ short passableArcCount(short x, short y) { newX = x + cDirs[dir][0]; newY = y + cDirs[dir][1]; // Counts every transition from passable to impassable or vice-versa on the way around the cell: - if ((coordinatesAreInMap(newX, newY) && cellIsPassableOrDoor(newX, newY)) - != (coordinatesAreInMap(oldX, oldY) && cellIsPassableOrDoor(oldX, oldY))) { + if ((coordinatesAreInMap(newX, newY) && cellIsPassableOrDoor(newX, newY)) != (coordinatesAreInMap(oldX, oldY) && cellIsPassableOrDoor(oldX, oldY))) { arcCount++; } } @@ -177,10 +171,9 @@ void analyzeMap(boolean calculateChokeMap) { // first find all of the loops rogue.staleLoopMap = false; - for(i=0; i 2) { - if (!passMap[i-1][j] && !passMap[i+1][j] || !passMap[i][j-1] && !passMap[i][j+1]) { + if (!passMap[i - 1][j] && !passMap[i + 1][j] || !passMap[i][j - 1] && !passMap[i][j + 1]) { pmap[i][j].flags |= IS_CHOKEPOINT; } break; @@ -260,8 +250,8 @@ void analyzeMap(boolean calculateChokeMap) { // The cost of all of this is one depth-first flood-fill per open point that is adjacent to a chokepoint. // Start by setting the chokepoint values really high, and roping off room machines. - for(i=0; i= 4) { - // Now, on the chokemap, all of those flooded cells should take the lesser of their current value or this resultant number. - for(i2=0; i2 minimumPathingDistance) { // and if the pathing distance between the two flanking floor tiles exceeds minimumPathingDistance, - grid[x][y] = 2; // then turn the tile into a doorway. - costMap[x][y] = 1; // (Cost map also needs updating.) + if (pathMap[oppX][oppY] > minimumPathingDistance) { // and if the pathing distance between the two flanking floor tiles + // exceeds minimumPathingDistance, + grid[x][y] = 2; // then turn the tile into a doorway. + costMap[x][y] = 1; // (Cost map also needs updating.) if (D_INSPECT_LEVELGEN) { - pos p = { x, y }; + pos p = {x, y}; plotCharWithColor(G_CLOSED_DOOR, mapToWindow(p), &black, &green); } break; @@ -387,18 +375,16 @@ boolean addTileToMachineInteriorAndIterate(char interior[DCOLS][DROWS], short st newX = startX + nbDirs[dir][0]; newY = startY + nbDirs[dir][1]; if (coordinatesAreInMap(newX, newY)) { - if ((pmap[newX][newY].flags & HAS_ITEM) - || ((pmap[newX][newY].flags & IS_IN_MACHINE) && !(pmap[newX][newY].flags & IS_GATE_SITE))) { + if ((pmap[newX][newY].flags & HAS_ITEM) || ((pmap[newX][newY].flags & IS_IN_MACHINE) && !(pmap[newX][newY].flags & IS_GATE_SITE))) { // Abort if there's an item in the room. // Items haven't been populated yet, so the only way this could happen is if another machine // previously placed an item here. // Also abort if we're touching another machine at any point other than a gate tile. return false; } - if (!interior[newX][newY] - && chokeMap[newX][newY] <= chokeMap[startX][startY] // don't have to worry about walls since they're all 30000 + if (!interior[newX][newY] && chokeMap[newX][newY] <= chokeMap[startX][startY] // don't have to worry about walls since they're all 30000 && !(pmap[newX][newY].flags & IS_IN_MACHINE)) { - //goodSoFar = goodSoFar && addTileToMachineInteriorAndIterate(interior, newX, newY); + // goodSoFar = goodSoFar && addTileToMachineInteriorAndIterate(interior, newX, newY); if (goodSoFar) { goodSoFar = addTileToMachineInteriorAndIterate(interior, newX, newY); } @@ -411,8 +397,8 @@ boolean addTileToMachineInteriorAndIterate(char interior[DCOLS][DROWS], short st void copyMap(pcell from[DCOLS][DROWS], pcell to[DCOLS][DROWS]) { short i, j; - for(i=0; icategory & (STAFF | WAND | POTION | SCROLL | RING | WEAPON | ARMOR | CHARM)) { for (i = 0; i < itemCount; i++) { - if (spawnedItems[i]->category == theItem->category - && spawnedItems[i]->kind == theItem->kind) { + if (spawnedItems[i]->category == theItem->category && spawnedItems[i]->kind == theItem->kind) { return true; } @@ -435,11 +420,11 @@ boolean itemIsADuplicate(item *theItem, item **spawnedItems, short itemCount) { boolean blueprintQualifies(short i, unsigned long requiredMachineFlags) { if (blueprintCatalog[i].depthRange[0] > rogue.depthLevel || blueprintCatalog[i].depthRange[1] < rogue.depthLevel - // Must have the required flags: + // Must have the required flags: || (~(blueprintCatalog[i].flags) & requiredMachineFlags) - // May NOT have BP_ADOPT_ITEM unless that flag is required: + // May NOT have BP_ADOPT_ITEM unless that flag is required: || (blueprintCatalog[i].flags & BP_ADOPT_ITEM & ~requiredMachineFlags) - // May NOT have BP_VESTIBULE unless that flag is required: + // May NOT have BP_VESTIBULE unless that flag is required: || (blueprintCatalog[i].flags & BP_VESTIBULE & ~requiredMachineFlags)) { return false; @@ -450,10 +435,10 @@ boolean blueprintQualifies(short i, unsigned long requiredMachineFlags) { void abortItemsAndMonsters(item *spawnedItems[MACHINES_BUFFER_LENGTH], creature *spawnedMonsters[MACHINES_BUFFER_LENGTH]) { short i, j; - for (i=0; icarriedItem == spawnedItems[i]) { spawnedMonsters[j]->carriedItem = NULL; @@ -463,35 +448,25 @@ void abortItemsAndMonsters(item *spawnedItems[MACHINES_BUFFER_LENGTH], creature deleteItem(spawnedItems[i]); spawnedItems[i] = NULL; } - for (i=0; i 1) { + if ((featureFlags & MF_NOT_IN_HALLWAY) && passableArcCount(x, y) > 1) { return false; } // No building along the perimeter of the level if it's prohibited. - if ((featureFlags & MF_NOT_ON_LEVEL_PERIMETER) - && (x == 0 || x == DCOLS - 1 || y == 0 || y == DROWS - 1)) { + if ((featureFlags & MF_NOT_ON_LEVEL_PERIMETER) && (x == 0 || x == DCOLS - 1 || y == 0 || y == DROWS - 1)) { return false; } @@ -509,8 +484,7 @@ boolean cellIsFeatureCandidate(short x, short y, } // Must be in the viewmap if the appropriate flag is set. - if ((featureFlags & (MF_IN_VIEW_OF_ORIGIN | MF_IN_PASSABLE_VIEW_OF_ORIGIN)) - && !viewMap[x][y]) { + if ((featureFlags & (MF_IN_VIEW_OF_ORIGIN | MF_IN_PASSABLE_VIEW_OF_ORIGIN)) && !viewMap[x][y]) { return false; } @@ -520,9 +494,7 @@ boolean cellIsFeatureCandidate(short x, short y, for (dir = 0; dir < 4; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) - && distance > distanceMap[newX][newY] + 1) { + if (coordinatesAreInMap(newX, newY) && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) && distance > distanceMap[newX][newY] + 1) { distance = distanceMap[newX][newY] + 1; } @@ -531,32 +503,27 @@ boolean cellIsFeatureCandidate(short x, short y, distance = distanceMap[x][y]; } - if (distance > distanceBound[1] // distance exceeds max - || distance < distanceBound[0]) { // distance falls short of min + if (distance > distanceBound[1] // distance exceeds max + || distance < distanceBound[0]) { // distance falls short of min return false; } - if (featureFlags & MF_BUILD_IN_WALLS) { // If we're supposed to build in a wall... - if (!interior[x][y] - && (pmap[x][y].machineNumber == 0 || pmap[x][y].machineNumber == machineNumber) - && cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) { // ...and this location is a wall that's not already machined... - for (dir=0; dir<4; dir++) { + if (featureFlags & MF_BUILD_IN_WALLS) { // If we're supposed to build in a wall... + if (!interior[x][y] && (pmap[x][y].machineNumber == 0 || pmap[x][y].machineNumber == machineNumber) && cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) { // ...and this location is a wall that's not already machined... + for (dir = 0; dir < 4; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) // ...and it's next to an interior spot or permitted elsewhere and next to passable spot... - && ((interior[newX][newY] && !(newX==originX && newY==originY)) - || ((featureFlags & MF_BUILD_ANYWHERE_ON_LEVEL) - && !cellHasTerrainFlag(newX, newY, T_PATHING_BLOCKER) - && pmap[newX][newY].machineNumber == 0))) { - return true; // ...then we're golden! + if (coordinatesAreInMap(newX, newY) // ...and it's next to an interior spot or permitted elsewhere and + // next to passable spot... + && ((interior[newX][newY] && !(newX == originX && newY == originY)) || ((featureFlags & MF_BUILD_ANYWHERE_ON_LEVEL) && !cellHasTerrainFlag(newX, newY, T_PATHING_BLOCKER) && pmap[newX][newY].machineNumber == 0))) { + return true; // ...then we're golden! } } } - return false; // Otherwise, no can do. + return false; // Otherwise, no can do. } else if (cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) { // Can't build in a wall unless instructed to do so. return false; } else if (featureFlags & MF_BUILD_ANYWHERE_ON_LEVEL) { - if ((featureFlags & MF_GENERATE_ITEM) - && (cellHasTerrainFlag(x, y, T_OBSTRUCTS_ITEMS | T_PATHING_BLOCKER) || (pmap[x][y].flags & (IS_CHOKEPOINT | IN_LOOP | IS_IN_MACHINE)))) { + if ((featureFlags & MF_GENERATE_ITEM) && (cellHasTerrainFlag(x, y, T_OBSTRUCTS_ITEMS | T_PATHING_BLOCKER) || (pmap[x][y].flags & (IS_CHOKEPOINT | IN_LOOP | IS_IN_MACHINE)))) { return false; } else { return !(pmap[x][y].flags & IS_IN_MACHINE); @@ -567,11 +534,11 @@ boolean cellIsFeatureCandidate(short x, short y, return false; } - void addLocationToKey(item *theItem, short x, short y, boolean disposableHere) { short i; - for (i=0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++); + for (i = 0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++) + ; theItem->keyLoc[i].x = x; theItem->keyLoc[i].y = y; theItem->keyLoc[i].disposableHere = disposableHere; @@ -580,7 +547,8 @@ void addLocationToKey(item *theItem, short x, short y, boolean disposableHere) { void addMachineNumberToKey(item *theItem, short machineNumber, boolean disposableHere) { short i; - for (i=0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++); + for (i = 0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++) + ; theItem->keyLoc[i].machine = machineNumber; theItem->keyLoc[i].disposableHere = disposableHere; } @@ -592,17 +560,15 @@ void expandMachineInterior(char interior[DCOLS][DROWS], short minimumInteriorNei do { madeChange = false; - for(i=1; i 0) { pathingGrid[i][j] = 0; @@ -791,8 +752,7 @@ void redesignInterior(char interior[DCOLS][DROWS], short originX, short originY, newX = i + nbDirs[dir][0]; newY = j + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && pathingGrid[newX][newY] < pathingGrid[i][j]) { + if (coordinatesAreInMap(newX, newY) && pathingGrid[newX][newY] < pathingGrid[i][j]) { grid[i][j] = 1; i = newX; @@ -804,7 +764,7 @@ void redesignInterior(char interior[DCOLS][DROWS], short originX, short originY, if (D_INSPECT_MACHINES) { dumpLevelToScreen(); displayGrid(pathingGrid); - pos p = { i, j }; + pos p = {i, j}; plotCharWithColor('X', mapToWindow(p), &black, &orange); temporaryMessage("Orphan connecting:", REQUIRE_ACKNOWLEDGMENT); } @@ -815,8 +775,8 @@ void redesignInterior(char interior[DCOLS][DROWS], short originX, short originY, } addLoops(grid, 10); - for(i=0; i= 0) { pmap[i][j].layers[SURFACE] = pmap[i][j].layers[GAS] = NOTHING; @@ -839,7 +799,8 @@ void prepareInteriorWithMachineFlags(char interior[DCOLS][DROWS], short originX, enum dungeonLayers layer; enum directions dir; - // If requested, clear and expand the room as far as possible until either it's convex or it bumps into surrounding rooms + // If requested, clear and expand the room as far as possible until either it's convex or it bumps into surrounding + // rooms if (flags & BP_MAXIMIZE_INTERIOR) { expandMachineInterior(interior, 1); } else if (flags & BP_OPEN_INTERIOR) { @@ -848,10 +809,10 @@ void prepareInteriorWithMachineFlags(char interior[DCOLS][DROWS], short originX, // If requested, cleanse the interior -- no interesting terrain allowed. if (flags & BP_PURGE_INTERIOR) { - for(i=0; inumberBlueprints; i++) { + for (i = 1; i < gameConst->numberBlueprints; i++) { if (blueprintQualifies(i, requiredMachineFlags)) { totalFreq += blueprintCatalog[i].frequency; } @@ -1029,15 +978,14 @@ boolean buildAMachine(enum machineTypes bp, if (distanceMap) { freeGrid(distanceMap); } - if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: Failed to build a machine because no suitable blueprints were available.", - rogue.depthLevel); + if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: Failed to build a machine because no suitable blueprints were available.", rogue.depthLevel); free(p); return false; } // Pick from among the suitable blueprints. randIndex = rand_range(1, totalFreq); - for (i=1; inumberBlueprints; i++) { + for (i = 1; i < gameConst->numberBlueprints; i++) { if (blueprintQualifies(i, requiredMachineFlags)) { if (randIndex <= blueprintCatalog[i].frequency) { bp = i; @@ -1049,7 +997,7 @@ boolean buildAMachine(enum machineTypes bp, } // If we don't have a blueprint yet, something went wrong. - brogueAssert(bp>0); + brogueAssert(bp > 0); } // Find a location and map out the machine interior. @@ -1061,15 +1009,13 @@ boolean buildAMachine(enum machineTypes bp, if (chooseLocation) { analyzeMap(true); // Make sure the chokeMap is up to date. totalFreq = 0; - for(i=0; i= blueprintCatalog[bp].roomSize[0] - && chokeMap[i][j] <= blueprintCatalog[bp].roomSize[1]) { - - //DEBUG printf("\nDepth %i: Gate site qualified with interior size of %i.", rogue.depthLevel, chokeMap[i][j]); - p->gateCandidates[totalFreq] = (pos){ .x = i, .y = j }; + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS && totalFreq < 50; j++) { + if ((pmap[i][j].flags & IS_GATE_SITE) && !(pmap[i][j].flags & IS_IN_MACHINE) && chokeMap[i][j] >= blueprintCatalog[bp].roomSize[0] && chokeMap[i][j] <= blueprintCatalog[bp].roomSize[1]) { + + // DEBUG printf("\nDepth %i: Gate site qualified with interior size of %i.", + // rogue.depthLevel, chokeMap[i][j]); + p->gateCandidates[totalFreq] = (pos){.x = i, .y = j}; totalFreq++; } } @@ -1085,9 +1031,10 @@ boolean buildAMachine(enum machineTypes bp, if (distanceMap) { freeGrid(distanceMap); } - if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: Failed to build a machine; there was no eligible door candidate for the chosen room machine from blueprint %i.", - rogue.depthLevel, - bp); + if (D_MESSAGE_MACHINE_GENERATION) + printf("\nDepth %i: Failed to build a machine; there was no eligible door candidate for the " + "chosen room machine from blueprint %i.", + rogue.depthLevel, bp); free(p); return false; } @@ -1104,9 +1051,10 @@ boolean buildAMachine(enum machineTypes bp, if (distanceMap) { freeGrid(distanceMap); } - if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: ERROR: Attempted to build a door machine from blueprint %i without a location being provided.", - rogue.depthLevel, - bp); + if (D_MESSAGE_MACHINE_GENERATION) + printf("\nDepth %i: ERROR: Attempted to build a door machine from blueprint %i without a location " + "being provided.", + rogue.depthLevel, bp); free(p); return false; } @@ -1114,9 +1062,7 @@ boolean buildAMachine(enum machineTypes bp, if (distanceMap) { freeGrid(distanceMap); } - if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: Failed to build a door machine from blueprint %i; not enough room.", - rogue.depthLevel, - bp); + if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: Failed to build a door machine from blueprint %i; not enough room.", rogue.depthLevel, bp); free(p); return false; } @@ -1143,22 +1089,24 @@ boolean buildAMachine(enum machineTypes bp, fillGrid(distanceMap, 0); calculateDistances(distanceMap, originX, originY, T_PATHING_BLOCKER, NULL, true, false); qualifyingTileCount = 0; // Keeps track of how many interior cells we've added. - totalFreq = rand_range(blueprintCatalog[bp].roomSize[0], blueprintCatalog[bp].roomSize[1]); // Keeps track of the goal size. + totalFreq = rand_range(blueprintCatalog[bp].roomSize[0], + blueprintCatalog[bp].roomSize[1]); // Keeps track of the goal size. fillSequentialList(p->sCols, DCOLS); shuffleList(p->sCols, DCOLS); fillSequentialList(p->sRows, DROWS); shuffleList(p->sRows, DROWS); - for (k=0; k<1000 && qualifyingTileCount < totalFreq; k++) { - for(i=0; isCols[i]][p->sRows[j]] == k) { p->interior[p->sCols[i]][p->sRows[j]] = true; qualifyingTileCount++; if (pmap[p->sCols[i]][p->sRows[j]].flags & (HAS_ITEM | HAS_MONSTER | IS_IN_MACHINE)) { - // Abort if we've entered another machine or engulfed another machine's item or monster. + // Abort if we've entered another machine or engulfed another machine's item or + // monster. tryAgain = true; qualifyingTileCount = totalFreq; // This is a hack to drop out of these three for-loops. } @@ -1168,15 +1116,14 @@ boolean buildAMachine(enum machineTypes bp, } // Now make sure the interior map satisfies the machine's qualifications. - if ((blueprintCatalog[bp].flags & BP_TREAT_AS_BLOCKING) - && levelIsDisconnectedWithBlockingMap(p->interior, false)) { + if ((blueprintCatalog[bp].flags & BP_TREAT_AS_BLOCKING) && levelIsDisconnectedWithBlockingMap(p->interior, false)) { tryAgain = true; - } else if ((blueprintCatalog[bp].flags & BP_REQUIRE_BLOCKING) - && levelIsDisconnectedWithBlockingMap(p->interior, true) < 100) { + } else if ((blueprintCatalog[bp].flags & BP_REQUIRE_BLOCKING) && levelIsDisconnectedWithBlockingMap(p->interior, true) < 100) { tryAgain = true; // BP_REQUIRE_BLOCKING needs some work to make sure the disconnect is interesting. } // If locationFailsafe runs out, tryAgain will still be true, and we'll try a different machine. - // If we're not choosing the blueprint, then don't bother with the locationFailsafe; just use the higher-level failsafe. + // If we're not choosing the blueprint, then don't bother with the locationFailsafe; just use the + // higher-level failsafe. } while (chooseBP && tryAgain && --locationFailsafe); } @@ -1193,16 +1140,18 @@ boolean buildAMachine(enum machineTypes bp, // Now loop if necessary. } while (tryAgain); - // This is the point of no return. Back up the level so it can be restored if we have to abort this machine after this point. + // This is the point of no return. Back up the level so it can be restored if we have to abort this machine after + // this point. copyMap(pmap, p->levelBackup); - // Perform any transformations to the interior indicated by the blueprint flags, including expanding the interior if requested. + // Perform any transformations to the interior indicated by the blueprint flags, including expanding the interior if + // requested. prepareInteriorWithMachineFlags(p->interior, originX, originY, blueprintCatalog[bp].flags, blueprintCatalog[bp].dungeonProfileType); // If necessary, label the interior as IS_IN_AREA_MACHINE or IS_IN_ROOM_MACHINE and mark down the number. machineNumber = ++rogue.machineNumber; // Reserve this machine number, starting with 1. - for(i=0; iinterior[i][j]) { pmap[i][j].flags |= ((blueprintCatalog[bp].flags & BP_ROOM) ? IS_IN_ROOM_MACHINE : IS_IN_AREA_MACHINE); pmap[i][j].machineNumber = machineNumber; @@ -1220,32 +1169,32 @@ boolean buildAMachine(enum machineTypes bp, } } -// DEBUG printf("\n\nWorking on blueprint %i, with origin at (%i, %i). Here's the initial interior map:", bp, originX, originY); -// DEBUG logBuffer(interior); + // DEBUG printf("\n\nWorking on blueprint %i, with origin at (%i, %i). Here's the initial interior map:", bp, + // originX, originY); DEBUG logBuffer(interior); - // Calculate the distance map (so that features that want to be close to or far from the origin can be placed accordingly) - // and figure out the 33rd and 67th percentiles for features that want to be near or far from the origin. + // Calculate the distance map (so that features that want to be close to or far from the origin can be placed + // accordingly) and figure out the 33rd and 67th percentiles for features that want to be near or far from the + // origin. if (!distanceMap) { distanceMap = allocGrid(); } fillGrid(distanceMap, 0); calculateDistances(distanceMap, originX, originY, T_PATHING_BLOCKER, NULL, true, true); qualifyingTileCount = 0; - for (i=0; i<100; i++) { + for (i = 0; i < 100; i++) { p->distances[i] = 0; } - for(i=0; iinterior[i][j] - && distanceMap[i][j] < 100) { + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS; j++) { + if (p->interior[i][j] && distanceMap[i][j] < 100) { p->distances[distanceMap[i][j]]++; // create a histogram of distances -- poor man's sort function qualifyingTileCount++; } } } - distance25 = (int) (qualifyingTileCount / 4); - distance75 = (int) (3 * qualifyingTileCount / 4); - for (i=0; i<100; i++) { + distance25 = (int)(qualifyingTileCount / 4); + distance75 = (int)(3 * qualifyingTileCount / 4); + for (i = 0; i < 100; i++) { if (distance25 <= p->distances[i]) { distance25 = i; break; @@ -1253,7 +1202,7 @@ boolean buildAMachine(enum machineTypes bp, distance25 -= p->distances[i]; } } - for (i=0; i<100; i++) { + for (i = 0; i < 100; i++) { if (distance75 <= p->distances[i]) { distance75 = i; break; @@ -1261,17 +1210,19 @@ boolean buildAMachine(enum machineTypes bp, distance75 -= p->distances[i]; } } - //DEBUG printf("\nDistances calculated: 33rd percentile of distance is %i, and 67th is %i.", distance25, distance75); + // DEBUG printf("\nDistances calculated: 33rd percentile of distance is %i, and 67th is %i.", distance25, + // distance75); - // Now decide which features will be skipped -- of the features marked MF_ALTERNATIVE, skip all but one, chosen randomly. - // Then repeat and do the same with respect to MF_ALTERNATIVE_2, to provide up to two independent sets of alternative features per machine. + // Now decide which features will be skipped -- of the features marked MF_ALTERNATIVE, skip all but one, chosen + // randomly. Then repeat and do the same with respect to MF_ALTERNATIVE_2, to provide up to two independent sets of + // alternative features per machine. - for (i=0; i 0) { randIndex = rand_range(1, totalFreq); - for (i=0; iinterior, p->occupied, p->viewMap, distanceMap, - machineNumber, feature->flags, blueprintCatalog[bp].flags)) { + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS; j++) { + if (cellIsFeatureCandidate(i, j, originX, originY, distanceBound, p->interior, p->occupied, p->viewMap, distanceMap, machineNumber, feature->flags, blueprintCatalog[bp].flags)) { qualifyingTileCount++; p->candidates[i][j] = true; } else { @@ -1361,7 +1309,8 @@ boolean buildAMachine(enum machineTypes bp, } if (feature->flags & MF_EVERYWHERE & ~MF_BUILD_AT_ORIGIN) { - // Generate everywhere that qualifies -- instead of randomly picking tiles, keep spawning until we run out of eligible tiles. + // Generate everywhere that qualifies -- instead of randomly picking tiles, keep spawning until we run + // out of eligible tiles. generateEverywhere = true; } else { // build as many instances as required @@ -1385,14 +1334,14 @@ boolean buildAMachine(enum machineTypes bp, featX = -1; featY = -1; randIndex = rand_range(1, qualifyingTileCount); - for(i=0; icandidates[i][j]) { if (randIndex == 1) { // This is the place! featX = i; featY = j; - i = DCOLS; // break out of the loops + i = DCOLS; // break out of the loops j = DROWS; } else { randIndex--; @@ -1407,17 +1356,16 @@ boolean buildAMachine(enum machineTypes bp, DFSucceeded = terrainSucceeded = true; - // Try to build the DF first, if any, since we don't want it to be disrupted by subsequently placed terrain. + // Try to build the DF first, if any, since we don't want it to be disrupted by subsequently placed + // terrain. if (feature->featureDF) { - DFSucceeded = spawnDungeonFeature(featX, featY, &dungeonFeatureCatalog[feature->featureDF], false, - !(feature->flags & MF_PERMIT_BLOCKING)); + DFSucceeded = spawnDungeonFeature(featX, featY, &dungeonFeatureCatalog[feature->featureDF], false, !(feature->flags & MF_PERMIT_BLOCKING)); } // Now try to place the terrain tile, if any. if (DFSucceeded && feature->terrain) { // Must we check for blocking? - if (!(feature->flags & MF_PERMIT_BLOCKING) - && ((tileCatalog[feature->terrain].flags & T_PATHING_BLOCKER) || (feature->flags & MF_TREAT_AS_BLOCKING))) { + if (!(feature->flags & MF_PERMIT_BLOCKING) && ((tileCatalog[feature->terrain].flags & T_PATHING_BLOCKER) || (feature->flags & MF_TREAT_AS_BLOCKING))) { // Yes, check for blocking. zeroOutGrid(p->blockingMap); @@ -1429,19 +1377,17 @@ boolean buildAMachine(enum machineTypes bp, } } - // OK, if placement was successful, clear some personal space around the feature so subsequent features can't be generated too close. - // Personal space of 0 means nothing gets cleared, 1 means that only the tile itself gets cleared, and 2 means the 3x3 grid centered on it. + // OK, if placement was successful, clear some personal space around the feature so subsequent features + // can't be generated too close. Personal space of 0 means nothing gets cleared, 1 means that only the + // tile itself gets cleared, and 2 means the 3x3 grid centered on it. if (DFSucceeded && terrainSucceeded) { - for (i = featX - personalSpace + 1; - i <= featX + personalSpace - 1; - i++) { - for (j = featY - personalSpace + 1; - j <= featY + personalSpace - 1; - j++) { + for (i = featX - personalSpace + 1; i <= featX + personalSpace - 1; i++) { + for (j = featY - personalSpace + 1; j <= featY + personalSpace - 1; j++) { if (coordinatesAreInMap(i, j)) { if (p->candidates[i][j]) { - brogueAssert(!p->occupied[i][j] || (i == originX && j == originY)); // Candidates[][] should never be true where occupied[][] is true. + brogueAssert(!p->occupied[i][j] || (i == originX && j == originY)); // Candidates[][] should never be + // true where occupied[][] is true. p->candidates[i][j] = false; qualifyingTileCount--; } @@ -1450,7 +1396,7 @@ boolean buildAMachine(enum machineTypes bp, } } instance++; // we've placed an instance - //DEBUG printf("\nPlaced instance #%i of feature %i at (%i, %i).", instance, feat, featX, featY); + // DEBUG printf("\nPlaced instance #%i of feature %i at (%i, %i).", instance, feat, featX, featY); } if (DFSucceeded && terrainSucceeded) { // Proceed only if the terrain stuff for this instance succeeded. @@ -1467,8 +1413,7 @@ boolean buildAMachine(enum machineTypes bp, } // Generate an item as necessary. - if ((feature->flags & MF_GENERATE_ITEM) - || (adoptiveItem && (feature->flags & MF_ADOPT_ITEM) && (blueprintCatalog[bp].flags & BP_ADOPT_ITEM))) { + if ((feature->flags & MF_GENERATE_ITEM) || (adoptiveItem && (feature->flags & MF_ADOPT_ITEM) && (blueprintCatalog[bp].flags & BP_ADOPT_ITEM))) { // Are we adopting an item instead of generating one? if (adoptiveItem && (feature->flags & MF_ADOPT_ITEM) && (blueprintCatalog[bp].flags & BP_ADOPT_ITEM)) { theItem = adoptiveItem; @@ -1477,10 +1422,10 @@ boolean buildAMachine(enum machineTypes bp, // Have to create an item ourselves. theItem = generateItem(feature->itemCategory, feature->itemKind); failsafe = 1000; - while ((theItem->flags & ITEM_CURSED) - || ((feature->flags & MF_REQUIRE_GOOD_RUNIC) && (!(theItem->flags & ITEM_RUNIC))) // runic if requested - || ((feature->flags & MF_NO_THROWING_WEAPONS) && theItem->category == WEAPON && theItem->quantity > 1) // no throwing weapons if prohibited - || itemIsADuplicate(theItem, p->spawnedItems, itemCount)) { // don't want to duplicates of rings, staffs, etc. + while ((theItem->flags & ITEM_CURSED) || ((feature->flags & MF_REQUIRE_GOOD_RUNIC) && (!(theItem->flags & ITEM_RUNIC))) // runic if requested + || ((feature->flags & MF_NO_THROWING_WEAPONS) && theItem->category == WEAPON && theItem->quantity > 1) // no throwing weapons if prohibited + || itemIsADuplicate(theItem, p->spawnedItems, + itemCount)) { // don't want to duplicates of rings, staffs, etc. deleteItem(theItem); theItem = generateItem(feature->itemCategory, feature->itemKind); if (failsafe <= 0) { @@ -1488,7 +1433,8 @@ boolean buildAMachine(enum machineTypes bp, } failsafe--; } - p->spawnedItems[itemCount] = theItem; // Keep a list of generated items so that we can delete them all if construction fails. + p->spawnedItems[itemCount] = theItem; // Keep a list of generated items so that we can + // delete them all if construction fails. itemCount++; } theItem->flags |= feature->itemFlags; @@ -1498,8 +1444,7 @@ boolean buildAMachine(enum machineTypes bp, if (feature->flags & MF_SKELETON_KEY) { addMachineNumberToKey(theItem, machineNumber, (feature->flags & MF_KEY_DISPOSABLE) ? true : false); } - if (!(feature->flags & MF_OUTSOURCE_ITEM_TO_MACHINE) - && !(feature->flags & MF_MONSTER_TAKE_ITEM)) { + if (!(feature->flags & MF_OUTSOURCE_ITEM_TO_MACHINE) && !(feature->flags & MF_MONSTER_TAKE_ITEM)) { // Place the item at the feature location. placeItem(theItem, featX, featY); } @@ -1512,7 +1457,7 @@ boolean buildAMachine(enum machineTypes bp, // Also, if we build a sub-machine, and it succeeds, but this (its parent machine) fails, // we pass the monsters and items that it spawned back to the parent, // so that if the parent fails, they can all be freed. - for (i=10; i > 0; i--) { + for (i = 10; i > 0; i--) { // First make sure our adopted item, if any, is not on the floor or in the pack already. // Otherwise, a previous attempt to place it may have put it on the floor in a different // machine, only to have that machine fail and be deleted, leaving the item remaining on @@ -1528,14 +1473,14 @@ boolean buildAMachine(enum machineTypes bp, // Now put the item up for adoption. if (success) { - // Success! Now we have to add that machine's items and monsters to our own list, so they - // all get deleted if this machine or its parent fails. - for (j=0; jspawnedItemsSub[j]; j++) { + // Success! Now we have to add that machine's items and monsters to our own list, so + // they all get deleted if this machine or its parent fails. + for (j = 0; j < MACHINES_BUFFER_LENGTH && p->spawnedItemsSub[j]; j++) { p->spawnedItems[itemCount] = p->spawnedItemsSub[j]; itemCount++; p->spawnedItemsSub[j] = NULL; } - for (j=0; jspawnedMonstersSub[j]; j++) { + for (j = 0; j < MACHINES_BUFFER_LENGTH && p->spawnedMonstersSub[j]; j++) { p->spawnedMonsters[monsterCount] = p->spawnedMonstersSub[j]; monsterCount++; p->spawnedMonstersSub[j] = NULL; @@ -1545,7 +1490,10 @@ boolean buildAMachine(enum machineTypes bp, } if (!i) { - if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: Failed to place blueprint %i because it requires an adoptive machine and we couldn't place one.", rogue.depthLevel, bp); + if (D_MESSAGE_MACHINE_GENERATION) + printf("\nDepth %i: Failed to place blueprint %i because it requires an adoptive " + "machine and we couldn't place one.", + rogue.depthLevel, bp); // failure! abort! copyMap(p->levelBackup, pmap); abortItemsAndMonsters(p->spawnedItems, p->spawnedMonsters); @@ -1557,28 +1505,23 @@ boolean buildAMachine(enum machineTypes bp, } // Generate a horde as necessary. - if ((feature->flags & MF_GENERATE_HORDE) - || feature->monsterID) { + if ((feature->flags & MF_GENERATE_HORDE) || feature->monsterID) { if (feature->flags & MF_GENERATE_HORDE) { - monst = spawnHorde(0, - featX, - featY, - ((HORDE_IS_SUMMONED | HORDE_LEADER_CAPTIVE) & ~(feature->hordeFlags)), - feature->hordeFlags); + monst = spawnHorde(0, featX, featY, ((HORDE_IS_SUMMONED | HORDE_LEADER_CAPTIVE) & ~(feature->hordeFlags)), feature->hordeFlags); if (monst) { monst->bookkeepingFlags |= MB_JUST_SUMMONED; } } if (feature->monsterID) { - monst = monsterAtLoc((pos){ featX, featY }); + monst = monsterAtLoc((pos){featX, featY}); if (monst) { killCreature(monst, true); // If there's already a monster here, quietly bury the body. } monst = generateMonster(feature->monsterID, true, true); if (monst) { - monst->loc = (pos){ .x = featX, .y = featY }; + monst->loc = (pos){.x = featX, .y = featY}; pmapAt(monst->loc)->flags |= HAS_MONSTER; monst->bookkeepingFlags |= MB_JUST_SUMMONED; } @@ -1642,14 +1585,16 @@ boolean buildAMachine(enum machineTypes bp, } } while ((feature->flags & MF_REPEAT_UNTIL_NO_PROGRESS) && instance >= feature->minimumInstanceCount); - //DEBUG printf("\nFinished feature %i. Here's the candidates map:", feat); - //DEBUG logBuffer(candidates); + // DEBUG printf("\nFinished feature %i. Here's the candidates map:", feat); + // DEBUG logBuffer(candidates); if (instance < feature->minimumInstanceCount && !(feature->flags & MF_REPEAT_UNTIL_NO_PROGRESS)) { // failure! abort! - if (D_MESSAGE_MACHINE_GENERATION) printf("\nDepth %i: Failed to place blueprint %i because of feature %i; needed %i instances but got only %i.", - rogue.depthLevel, bp, feat, feature->minimumInstanceCount, instance); + if (D_MESSAGE_MACHINE_GENERATION) + printf("\nDepth %i: Failed to place blueprint %i because of feature %i; needed %i instances but got " + "only %i.", + rogue.depthLevel, bp, feat, feature->minimumInstanceCount, instance); // Restore the map to how it was before we touched it. copyMap(p->levelBackup, pmap); @@ -1662,10 +1607,9 @@ boolean buildAMachine(enum machineTypes bp, // Clear out the interior flag for all non-wired cells, if requested. if (blueprintCatalog[bp].flags & BP_NO_INTERIOR_FLAG) { - for(i=0; ispawnedItems[i]; } } if (parentSpawnedMonsters) { - for (i=0; ispawnedMonsters[i]; } } @@ -1720,7 +1664,7 @@ void addMachines() { // Add reward rooms, if any: machineCount = 0; while (rogue.depthLevel <= gameConst->amuletLevel - && (rogue.rewardRoomsGenerated + machineCount) * gameConst->machinesPerLevelSuppressionMultiplier + gameConst->machinesPerLevelSuppressionOffset < rogue.depthLevel * gameConst->machinesPerLevelIncreaseFactor) { + && (rogue.rewardRoomsGenerated + machineCount) * gameConst->machinesPerLevelSuppressionMultiplier + gameConst->machinesPerLevelSuppressionOffset < rogue.depthLevel * gameConst->machinesPerLevelIncreaseFactor) { // try to build at least one every four levels on average machineCount++; } @@ -1747,7 +1691,7 @@ void runAutogenerators(boolean buildAreaMachines) { char grid[DCOLS][DROWS]; // Cycle through the autoGenerators. - for (AG=1; AGnumberAutogenerators; AG++) { + for (AG = 1; AG < gameConst->numberAutogenerators; AG++) { // Shortcut: gen = &(autoGeneratorCatalog[AG]); @@ -1769,8 +1713,8 @@ void runAutogenerators(boolean buildAreaMachines) { for (i = 0; i < count; i++) { // Find a location for DFs and terrain generations. - //if (randomMatchingLocation(&x, &y, gen->requiredDungeonFoundationType, NOTHING, -1)) { - //if (randomMatchingLocation(&x, &y, -1, -1, gen->requiredDungeonFoundationType)) { + // if (randomMatchingLocation(&x, &y, gen->requiredDungeonFoundationType, NOTHING, -1)) { + // if (randomMatchingLocation(&x, &y, -1, -1, gen->requiredDungeonFoundationType)) { if (randomMatchingLocation(&x, &y, gen->requiredDungeonFoundationType, gen->requiredLiquidFoundationType, -1)) { // Spawn the DF. @@ -1785,14 +1729,12 @@ void runAutogenerators(boolean buildAreaMachines) { } // Spawn the terrain if it's got the priority to spawn there and won't disrupt connectivity. - if (gen->terrain - && tileCatalog[pmap[x][y].layers[gen->layer]].drawPriority >= tileCatalog[gen->terrain].drawPriority) { + if (gen->terrain && tileCatalog[pmap[x][y].layers[gen->layer]].drawPriority >= tileCatalog[gen->terrain].drawPriority) { // Check connectivity. zeroOutGrid(grid); grid[x][y] = true; - if (!(tileCatalog[gen->terrain].flags & T_PATHING_BLOCKER) - || !levelIsDisconnectedWithBlockingMap(grid, false)) { + if (!(tileCatalog[gen->terrain].flags & T_PATHING_BLOCKER) || !levelIsDisconnectedWithBlockingMap(grid, false)) { // Build! pmap[x][y].layers[gen->layer] = gen->terrain; @@ -1830,33 +1772,23 @@ void cleanUpLakeBoundaries() { reverse = !reverse; failsafe--; - for (i = (reverse ? DCOLS - 2 : 1); - (reverse ? i > 0 : i < DCOLS - 1); - (reverse ? i-- : i++)) { + for (i = (reverse ? DCOLS - 2 : 1); (reverse ? i > 0 : i < DCOLS - 1); (reverse ? i-- : i++)) { - for (j = (reverse ? DROWS - 2 : 1); - (reverse ? j > 0 : j < DROWS - 1); - (reverse ? j-- : j++)) { + for (j = (reverse ? DROWS - 2 : 1); (reverse ? j > 0 : j < DROWS - 1); (reverse ? j-- : j++)) { - //assert(i >= 1 && i <= DCOLS - 2 && j >= 1 && j <= DROWS - 2); + // assert(i >= 1 && i <= DCOLS - 2 && j >= 1 && j <= DROWS - 2); - //if (cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) - if (cellHasTerrainFlag(i, j, T_LAKE_PATHING_BLOCKER | T_OBSTRUCTS_PASSABILITY) - && !cellHasTMFlag(i, j, TM_IS_SECRET) - && !(pmap[i][j].flags & IMPREGNABLE)) { + // if (cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) + if (cellHasTerrainFlag(i, j, T_LAKE_PATHING_BLOCKER | T_OBSTRUCTS_PASSABILITY) && !cellHasTMFlag(i, j, TM_IS_SECRET) && !(pmap[i][j].flags & IMPREGNABLE)) { subjectFlags = terrainFlags(i, j) & (T_LAKE_PATHING_BLOCKER | T_OBSTRUCTS_PASSABILITY); x = y = 0; - if ((terrainFlags(i - 1, j) & T_LAKE_PATHING_BLOCKER & ~subjectFlags) - && !cellHasTMFlag(i - 1, j, TM_IS_SECRET) - && !cellHasTMFlag(i + 1, j, TM_IS_SECRET) + if ((terrainFlags(i - 1, j) & T_LAKE_PATHING_BLOCKER & ~subjectFlags) && !cellHasTMFlag(i - 1, j, TM_IS_SECRET) && !cellHasTMFlag(i + 1, j, TM_IS_SECRET) && (terrainFlags(i - 1, j) & T_LAKE_PATHING_BLOCKER & ~subjectFlags) == (terrainFlags(i + 1, j) & T_LAKE_PATHING_BLOCKER & ~subjectFlags)) { x = i + 1; y = j; - } else if ((terrainFlags(i, j - 1) & T_LAKE_PATHING_BLOCKER & ~subjectFlags) - && !cellHasTMFlag(i, j - 1, TM_IS_SECRET) - && !cellHasTMFlag(i, j + 1, TM_IS_SECRET) + } else if ((terrainFlags(i, j - 1) & T_LAKE_PATHING_BLOCKER & ~subjectFlags) && !cellHasTMFlag(i, j - 1, TM_IS_SECRET) && !cellHasTMFlag(i, j + 1, TM_IS_SECRET) && (terrainFlags(i, j - 1) & T_LAKE_PATHING_BLOCKER & ~subjectFlags) == (terrainFlags(i, j + 1) & T_LAKE_PATHING_BLOCKER & ~subjectFlags)) { x = i; y = j + 1; @@ -1866,7 +1798,7 @@ void cleanUpLakeBoundaries() { for (layer = 0; layer < NUMBER_TERRAIN_LAYERS; layer++) { pmap[i][j].layers[layer] = pmap[x][y].layers[layer]; } - //pmap[i][j].layers[DUNGEON] = CRYSTAL_WALL; + // pmap[i][j].layers[DUNGEON] = CRYSTAL_WALL; } } } @@ -1880,23 +1812,20 @@ void removeDiagonalOpenings() { do { diagonalCornerRemoved = false; - for (i=0; i 6 - && rand_percent(50)) { - drawCircleOnGrid(grid, DCOLS/2, DROWS/2, rand_range(3, radius - 3), 0); + if (radius > 6 && rand_percent(50)) { + drawCircleOnGrid(grid, DCOLS / 2, DROWS / 2, rand_range(3, radius - 3), 0); } } @@ -2058,18 +1981,18 @@ void designChunkyRoom(short **grid) { short chunkCount = rand_range(2, 8); fillGrid(grid, 0); - drawCircleOnGrid(grid, DCOLS/2, DROWS/2, 2, 1); - minX = DCOLS/2 - 3; - maxX = DCOLS/2 + 3; - minY = DROWS/2 - 3; - maxY = DROWS/2 + 3; + drawCircleOnGrid(grid, DCOLS / 2, DROWS / 2, 2, 1); + minX = DCOLS / 2 - 3; + maxX = DCOLS / 2 + 3; + minY = DROWS / 2 - 3; + maxY = DROWS / 2 + 3; - for (i=0; i 0) { + if (!coordinatesAreInMap(i, j) || dungeonMap[i][j] > 0) { return false; } } @@ -2332,18 +2247,17 @@ void attachRooms(short **grid, const dungeonProfile *theDP, short attempts, shor short roomsBuilt, roomsAttempted; short **roomMap; pos doorSites[4]; - short i, x, y, sCoord[DCOLS*DROWS]; + short i, x, y, sCoord[DCOLS * DROWS]; enum directions dir, oppDir; - fillSequentialList(sCoord, DCOLS*DROWS); - shuffleList(sCoord, DCOLS*DROWS); + fillSequentialList(sCoord, DCOLS * DROWS); + shuffleList(sCoord, DCOLS * DROWS); roomMap = allocGrid(); for (roomsBuilt = roomsAttempted = 0; roomsBuilt < maxRoomCount && roomsAttempted < attempts; roomsAttempted++) { // Build a room in hyperspace. fillGrid(roomMap, 0); - designRandomRoom(roomMap, roomsAttempted <= attempts - 5 && rand_percent(theDP->corridorChance), - doorSites, theDP->roomFrequencies); + designRandomRoom(roomMap, roomsAttempted <= attempts - 5 && rand_percent(theDP->corridorChance), doorSites, theDP->roomFrequencies); if (D_INSPECT_LEVELGEN) { colorOverDungeon(&darkGray); @@ -2355,16 +2269,15 @@ void attachRooms(short **grid, const dungeonProfile *theDP, short attempts, shor temporaryMessage("Generating this room:", REQUIRE_ACKNOWLEDGMENT); } - // Slide hyperspace across real space, in a random but predetermined order, until the room matches up with a wall. - for (i = 0; i < DCOLS*DROWS; i++) { + // Slide hyperspace across real space, in a random but predetermined order, until the room matches up with a + // wall. + for (i = 0; i < DCOLS * DROWS; i++) { x = sCoord[i] / DROWS; y = sCoord[i] % DROWS; dir = directionOfDoorSite(grid, x, y); oppDir = oppositeDirection(dir); - if (dir != NO_DIRECTION - && doorSites[oppDir].x != -1 - && roomFitsAt(grid, roomMap, x - doorSites[oppDir].x, y - doorSites[oppDir].y)) { + if (dir != NO_DIRECTION && doorSites[oppDir].x != -1 && roomFitsAt(grid, roomMap, x - doorSites[oppDir].x, y - doorSites[oppDir].y)) { // Room fits here. if (D_INSPECT_LEVELGEN) { @@ -2391,7 +2304,7 @@ void adjustDungeonProfileForDepth(dungeonProfile *theProfile) { theProfile->roomFrequencies[0] += 20 * (100 - descentPercent) / 100; theProfile->roomFrequencies[1] += 10 * (100 - descentPercent) / 100; - theProfile->roomFrequencies[3] += 7 * (100 - descentPercent) / 100; + theProfile->roomFrequencies[3] += 7 * (100 - descentPercent) / 100; theProfile->roomFrequencies[5] += 10 * descentPercent / 100; theProfile->corridorChance += 80 * (100 - descentPercent) / 100; @@ -2436,9 +2349,9 @@ void carveDungeon(short **grid) { attachRooms(grid, &theDP, 35, 35); -// colorOverDungeon(&darkGray); -// hiliteGrid(grid, &white, 100); -// temporaryMessage("How does this finished level look?", REQUIRE_ACKNOWLEDGMENT); + // colorOverDungeon(&darkGray); + // hiliteGrid(grid, &white, 100); + // temporaryMessage("How does this finished level look?", REQUIRE_ACKNOWLEDGMENT); } void finishWalls(boolean includingDiagonals) { @@ -2446,15 +2359,14 @@ void finishWalls(boolean includingDiagonals) { boolean foundExposure; enum directions dir; - for (i=0; i=10; lakeMaxHeight--, lakeMaxWidth -= 2) { // lake generations + for (lakeMaxHeight = 15, lakeMaxWidth = 30; lakeMaxHeight >= 10; lakeMaxHeight--, lakeMaxWidth -= 2) { // lake generations fillGrid(grid, 0); createBlobOnGrid(grid, &lakeX, &lakeY, &lakeWidth, &lakeHeight, 5, 4, 4, lakeMaxWidth, lakeMaxHeight, 55, "ffffftttt", "ffffttttt"); -// if (D_INSPECT_LEVELGEN) { -// colorOverDungeon(&darkGray); -// hiliteGrid(grid, &white, 100); -// temporaryMessage("Generated a lake.", REQUIRE_ACKNOWLEDGMENT); -// } + // if (D_INSPECT_LEVELGEN) { + // colorOverDungeon(&darkGray); + // hiliteGrid(grid, &white, 100); + // temporaryMessage("Generated a lake.", REQUIRE_ACKNOWLEDGMENT); + // } - for (k=0; k<20; k++) { // placement attempts + for (k = 0; k < 20; k++) { // placement attempts // propose a position for the top-left of the grid in the dungeon x = rand_range(1 - lakeX, DCOLS - lakeWidth - lakeX - 2); y = rand_range(1 - lakeY, DROWS - lakeHeight - lakeY - 2); if (!lakeDisruptsPassability(grid, lakeMap, -x, -y)) { // level with lake is completely connected - //printf("Placed a lake!"); + // printf("Placed a lake!"); // copy in lake for (i = 0; i < lakeWidth; i++) { @@ -2652,13 +2555,12 @@ void designLakes(short **lakeMap) { void createWreath(short shallowLiquid, short wreathWidth, char wreathMap[DCOLS][DROWS]) { short i, j, k, l; - for (i=0; iamuletLevel - 1), 0, 67); - for (i=1; i= 3) { + } else if ((cellHasTerrainFlag(i + 1, j, T_PATHING_BLOCKER) ? 1 : 0) + (cellHasTerrainFlag(i - 1, j, T_PATHING_BLOCKER) ? 1 : 0) + (cellHasTerrainFlag(i, j + 1, T_PATHING_BLOCKER) ? 1 : 0) + + (cellHasTerrainFlag(i, j - 1, T_PATHING_BLOCKER) ? 1 : 0) + >= 3) { // If the door has three or more pathing blocker neighbors in the four cardinal directions, // then the door is orphaned and must be removed. pmap[i][j].layers[DUNGEON] = FLOOR; @@ -2724,8 +2624,8 @@ void finishDoors() { void clearLevel() { short i, j; - for( i=0; idepthAccelerator / 9) * rand_range(10, 20) / 10); - bridgeRatioY = (short) (100 + (400 + 100 * rogue.depthLevel * gameConst->depthAccelerator / 18) * rand_range(10, 20) / 10); + bridgeRatioX = (short)(100 + (100 + 100 * rogue.depthLevel * gameConst->depthAccelerator / 9) * rand_range(10, 20) / 10); + bridgeRatioY = (short)(100 + (400 + 100 * rogue.depthLevel * gameConst->depthAccelerator / 18) * rand_range(10, 20) / 10); fillSequentialList(nCols, DCOLS); shuffleList(nCols, DCOLS); fillSequentialList(nRows, DROWS); shuffleList(nRows, DROWS); - for (i2=1; i2 3) // Can't have bridges shorter than 3 spaces. - && foundExposure - && !cellHasTerrainFlag(k, j, T_PATHING_BLOCKER | T_CAN_BE_BRIDGED) // Must end on an unobstructed land tile. - && !pmap[k][j].machineNumber // Cannot end in a machine. + if (k < DCOLS && (k - i > 3) // Can't have bridges shorter than 3 spaces. + && foundExposure && !cellHasTerrainFlag(k, j, T_PATHING_BLOCKER | T_CAN_BE_BRIDGED) // Must end on an unobstructed land tile. + && !pmap[k][j].machineNumber // Cannot end in a machine. && 100 * pathingDistance(i, j, k, j, T_PATHING_BLOCKER) / (k - i) > bridgeRatioX) { // Must shorten the pathing distance enough. - for (l=i+1; l < k; l++) { + for (l = i + 1; l < k; l++) { pmap[l][j].layers[LIQUID] = BRIDGE; } pmap[i][j].layers[SURFACE] = BRIDGE_EDGE; @@ -2801,29 +2699,18 @@ boolean buildABridge() { // try a vertical bridge foundExposure = false; - for (k = j + 1; - k < DROWS - && !pmap[i][k].machineNumber - && cellHasTerrainFlag(i, k, T_CAN_BE_BRIDGED) - && !cellHasTMFlag(i, k, TM_IS_SECRET) - && !cellHasTerrainFlag(i, k, T_OBSTRUCTS_PASSABILITY) - && cellHasTerrainFlag(i-1, k, (T_CAN_BE_BRIDGED | T_OBSTRUCTS_PASSABILITY)) - && cellHasTerrainFlag(i+1, k, (T_CAN_BE_BRIDGED | T_OBSTRUCTS_PASSABILITY)); + for (k = j + 1; k < DROWS && !pmap[i][k].machineNumber && cellHasTerrainFlag(i, k, T_CAN_BE_BRIDGED) && !cellHasTMFlag(i, k, TM_IS_SECRET) && !cellHasTerrainFlag(i, k, T_OBSTRUCTS_PASSABILITY) + && cellHasTerrainFlag(i - 1, k, (T_CAN_BE_BRIDGED | T_OBSTRUCTS_PASSABILITY)) && cellHasTerrainFlag(i + 1, k, (T_CAN_BE_BRIDGED | T_OBSTRUCTS_PASSABILITY)); k++) { - if (!cellHasTerrainFlag(i-1, k, T_OBSTRUCTS_PASSABILITY) - && !cellHasTerrainFlag(i+1, k, T_OBSTRUCTS_PASSABILITY)) { + if (!cellHasTerrainFlag(i - 1, k, T_OBSTRUCTS_PASSABILITY) && !cellHasTerrainFlag(i + 1, k, T_OBSTRUCTS_PASSABILITY)) { foundExposure = true; } } - if (k < DROWS - && (k - j > 3) - && foundExposure - && !cellHasTerrainFlag(i, k, T_PATHING_BLOCKER | T_CAN_BE_BRIDGED) - && !pmap[i][k].machineNumber // Cannot end in a machine. + if (k < DROWS && (k - j > 3) && foundExposure && !cellHasTerrainFlag(i, k, T_PATHING_BLOCKER | T_CAN_BE_BRIDGED) && !pmap[i][k].machineNumber // Cannot end in a machine. && 100 * pathingDistance(i, j, i, k, T_PATHING_BLOCKER) / (k - j) > bridgeRatioY) { - for (l=j+1; l < k; l++) { + for (l = j + 1; l < k; l++) { pmap[i][l].layers[LIQUID] = BRIDGE; } pmap[i][j].layers[SURFACE] = BRIDGE_EDGE; @@ -2859,8 +2746,8 @@ void digDungeon() { grid = allocGrid(); carveDungeon(grid); addLoops(grid, 20); - for (i=0; icreatureState == MONSTER_SLEEPING || (monst->info.flags & MONST_IMMOBILE) || (monst->bookkeepingFlags & MB_CAPTIVE)) - && costMap[monst->loc.x][monst->loc.y] >= 0) { + creature *monst = nextCreature(&it); + if ((monst->creatureState == MONSTER_SLEEPING || (monst->info.flags & MONST_IMMOBILE) || (monst->bookkeepingFlags & MB_CAPTIVE)) && costMap[monst->loc.x][monst->loc.y] >= 0) { costMap[monst->loc.x][monst->loc.y] = PDS_FORBIDDEN; } @@ -2999,8 +2885,8 @@ void setUpWaypoints() { char grid[DCOLS][DROWS]; zeroOutGrid(grid); - for (i=0; i= tileCatalog[surfaceTileType].drawPriority) - // and we won't be painting into the surface layer when that cell forbids it, + // and we won't be painting into the surface layer when that cell forbids it, && !(layer == SURFACE && cellHasTerrainFlag(i, j, T_OBSTRUCTS_SURFACE_EFFECTS)) - // and, if requested, the fill won't violate the priority of the most important terrain in this cell: - && (!blockedByOtherLayers || tileCatalog[pmap[i][j].layers[highestPriorityLayer(i, j, true)]].drawPriority >= tileCatalog[surfaceTileType].drawPriority) - ) { + // and, if requested, the fill won't violate the priority of the most important terrain in this cell: + && (!blockedByOtherLayers || tileCatalog[pmap[i][j].layers[highestPriorityLayer(i, j, true)]].drawPriority >= tileCatalog[surfaceTileType].drawPriority)) { - if ((tileCatalog[surfaceTileType].flags & T_IS_FIRE) - && !(tileCatalog[pmap[i][j].layers[layer]].flags & T_IS_FIRE)) { + if ((tileCatalog[surfaceTileType].flags & T_IS_FIRE) && !(tileCatalog[pmap[i][j].layers[layer]].flags & T_IS_FIRE)) { pmap[i][j].flags |= CAUGHT_FIRE_THIS_TURN; } - if ((tileCatalog[pmap[i][j].layers[layer]].flags & T_PATHING_BLOCKER) - != (tileCatalog[surfaceTileType].flags & T_PATHING_BLOCKER)) { + if ((tileCatalog[pmap[i][j].layers[layer]].flags & T_PATHING_BLOCKER) != (tileCatalog[surfaceTileType].flags & T_PATHING_BLOCKER)) { rogue.staleLoopMap = true; } @@ -3216,7 +3092,7 @@ boolean fillSpawnMap(enum dungeonLayers layer, flavorMessage(tileFlavor(player.loc.x, player.loc.y)); } if (pmap[i][j].flags & (HAS_MONSTER)) { - monst = monsterAtLoc((pos){ i, j }); + monst = monsterAtLoc((pos){i, j}); applyInstantTileEffectsToCreature(monst); if (rogue.gameHasEnded) { return true; @@ -3239,12 +3115,7 @@ boolean fillSpawnMap(enum dungeonLayers layer, return accomplishedSomething; } -void spawnMapDF(short x, short y, - enum tileType propagationTerrain, - boolean requirePropTerrain, - short startProb, - short probDec, - char spawnMap[DCOLS][DROWS]) { +void spawnMapDF(short x, short y, enum tileType propagationTerrain, boolean requirePropTerrain, short startProb, short probDec, char spawnMap[DCOLS][DROWS]) { short i, j, dir, t, x2, y2; boolean madeChange; @@ -3257,15 +3128,13 @@ void spawnMapDF(short x, short y, madeChange = false; t++; for (i = 0; i < DCOLS; i++) { - for (j=0; j < DROWS; j++) { + for (j = 0; j < DROWS; j++) { if (spawnMap[i][j] == t - 1) { for (dir = 0; dir < 4; dir++) { x2 = i + nbDirs[dir][0]; y2 = j + nbDirs[dir][1]; - if (coordinatesAreInMap(x2, y2) - && (!requirePropTerrain || (propagationTerrain > 0 && cellHasTerrainType(x2, y2, propagationTerrain))) - && (!cellHasTerrainFlag(x2, y2, T_OBSTRUCTS_SURFACE_EFFECTS) || (propagationTerrain > 0 && cellHasTerrainType(x2, y2, propagationTerrain))) - && rand_percent(startProb)) { + if (coordinatesAreInMap(x2, y2) && (!requirePropTerrain || (propagationTerrain > 0 && cellHasTerrainType(x2, y2, propagationTerrain))) + && (!cellHasTerrainFlag(x2, y2, T_OBSTRUCTS_SURFACE_EFFECTS) || (propagationTerrain > 0 && cellHasTerrainType(x2, y2, propagationTerrain))) && rand_percent(startProb)) { spawnMap[x2][y2] = t; madeChange = true; @@ -3277,7 +3146,7 @@ void spawnMapDF(short x, short y, startProb -= probDec; if (t > 100) { for (i = 0; i < DCOLS; i++) { - for (j=0; j < DROWS; j++) { + for (j = 0; j < DROWS; j++) { if (spawnMap[i][j] == t) { spawnMap[i][j] = 2; } else if (spawnMap[i][j] > 0) { @@ -3296,21 +3165,13 @@ void spawnMapDF(short x, short y, void evacuateCreatures(char blockingMap[DCOLS][DROWS]) { creature *monst; - for (int i=0; iinfo)), - (HAS_MONSTER | HAS_PLAYER), - false, - false); + getQualifyingLocNear(&newLoc, i, j, true, blockingMap, forbiddenFlagsForMonster(&(monst->info)), (HAS_MONSTER | HAS_PLAYER), false, false); monst->loc = newLoc; pmap[i][j].flags &= ~(HAS_MONSTER | HAS_PLAYER); pmapAt(newLoc)->flags |= (monst == &player ? HAS_PLAYER : HAS_MONSTER); @@ -3326,8 +3187,7 @@ boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refr boolean blocking; boolean succeeded; - if ((feat->flags & DFF_RESURRECT_ALLY) - && !resurrectAlly(x, y)) { + if ((feat->flags & DFF_RESURRECT_ALLY) && !resurrectAlly(x, y)) { return false; } @@ -3339,10 +3199,7 @@ boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refr zeroOutGrid(blockingMap); // Blocking keeps track of whether to abort if it turns out that the DF would obstruct the level. - blocking = ((abortIfBlocking - && !(feat->flags & DFF_PERMIT_BLOCKING) - && ((tileCatalog[feat->tile].flags & (T_PATHING_BLOCKER)) - || (feat->flags & DFF_TREAT_AS_BLOCKING))) ? true : false); + blocking = ((abortIfBlocking && !(feat->flags & DFF_PERMIT_BLOCKING) && ((tileCatalog[feat->tile].flags & (T_PATHING_BLOCKER)) || (feat->flags & DFF_TREAT_AS_BLOCKING))) ? true : false); if (feat->tile) { if (feat->layer == GAS) { @@ -3353,40 +3210,35 @@ boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refr } succeeded = true; } else { - spawnMapDF(x, y, - feat->propagationTerrain, - (feat->propagationTerrain ? true : false), - feat->startProbability, - feat->probabilityDecrement, - blockingMap); + spawnMapDF(x, y, feat->propagationTerrain, (feat->propagationTerrain ? true : false), feat->startProbability, feat->probabilityDecrement, blockingMap); if (!blocking || !levelIsDisconnectedWithBlockingMap(blockingMap, false)) { - if (feat->flags & DFF_EVACUATE_CREATURES_FIRST) { // first, evacuate creatures if necessary, so that they do not re-trigger the tile. + if (feat->flags & DFF_EVACUATE_CREATURES_FIRST) { // first, evacuate creatures if necessary, so that + // they do not re-trigger the tile. evacuateCreatures(blockingMap); } - //succeeded = fillSpawnMap(feat->layer, feat->tile, blockingMap, (feat->flags & DFF_BLOCKED_BY_OTHER_LAYERS), refreshCell, (feat->flags & DFF_SUPERPRIORITY)); - fillSpawnMap(feat->layer, - feat->tile, - blockingMap, - (feat->flags & DFF_BLOCKED_BY_OTHER_LAYERS), - refreshCell, + // succeeded = fillSpawnMap(feat->layer, feat->tile, blockingMap, (feat->flags & + // DFF_BLOCKED_BY_OTHER_LAYERS), refreshCell, (feat->flags & DFF_SUPERPRIORITY)); + fillSpawnMap(feat->layer, feat->tile, blockingMap, (feat->flags & DFF_BLOCKED_BY_OTHER_LAYERS), refreshCell, (feat->flags & DFF_SUPERPRIORITY)); // this can tweak the spawn map too - succeeded = true; // fail ONLY if we blocked the level. We succeed even if, thanks to priority, nothing gets built. + succeeded = true; // fail ONLY if we blocked the level. We succeed even if, thanks to priority, nothing + // gets built. } else { succeeded = false; } } } else { blockingMap[x][y] = true; - succeeded = true; // Automatically succeed if there is no terrain to place. - if (feat->flags & DFF_EVACUATE_CREATURES_FIRST) { // first, evacuate creatures if necessary, so that they do not re-trigger the tile. + succeeded = true; // Automatically succeed if there is no terrain to place. + if (feat->flags & DFF_EVACUATE_CREATURES_FIRST) { // first, evacuate creatures if necessary, so that they do not + // re-trigger the tile. evacuateCreatures(blockingMap); } } if (succeeded && (feat->flags & DFF_CLEAR_OTHER_TERRAIN)) { - for (i=0; ilayer && layer != GAS) { @@ -3410,9 +3262,7 @@ boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refr } } - if (refreshCell - && (tileCatalog[feat->tile].flags & (T_IS_FIRE | T_AUTO_DESCENT)) - && cellHasTerrainFlag(player.loc.x, player.loc.y, (T_IS_FIRE | T_AUTO_DESCENT))) { + if (refreshCell && (tileCatalog[feat->tile].flags & (T_IS_FIRE | T_AUTO_DESCENT)) && cellHasTerrainFlag(player.loc.x, player.loc.y, (T_IS_FIRE | T_AUTO_DESCENT))) { applyInstantTileEffectsToCreature(&player); } @@ -3426,8 +3276,8 @@ boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refr if (succeeded) { if (feat->subsequentDF) { if (feat->flags & DFF_SUBSEQ_EVERYWHERE) { - for (i=0; isubsequentDF], refreshCell, abortIfBlocking); } @@ -3437,8 +3287,7 @@ boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refr spawnDungeonFeature(x, y, &dungeonFeatureCatalog[feat->subsequentDF], refreshCell, abortIfBlocking); } } - if (feat->tile - && (tileCatalog[feat->tile].flags & (T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_AUTO_DESCENT))) { + if (feat->tile && (tileCatalog[feat->tile].flags & (T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_AUTO_DESCENT))) { rogue.updatedMapToShoreThisTurn = false; } @@ -3475,9 +3324,10 @@ void restoreMonster(creature *monst, short **mapToStairs, short **mapToPit) { pmap[*x][*y].flags &= ~HAS_MONSTER; if (theMap) { - // STATUS_ENTERS_LEVEL_IN accounts for monster speed; convert back to map distance and subtract from distance to stairs + // STATUS_ENTERS_LEVEL_IN accounts for monster speed; convert back to map distance and subtract from + // distance to stairs turnCount = (theMap[monst->loc.x][monst->loc.y] - (monst->status[STATUS_ENTERS_LEVEL_IN] * 100 / monst->movementSpeed)); - for (i=0; i < turnCount; i++) { + for (i = 0; i < turnCount; i++) { if ((dir = nextStep(theMap, monst->loc.x, monst->loc.y, NULL, true)) != NO_DIRECTION) { monst->loc.x += nbDirs[dir][0]; monst->loc.y += nbDirs[dir][1]; @@ -3489,16 +3339,14 @@ void restoreMonster(creature *monst, short **mapToStairs, short **mapToPit) { monst->bookkeepingFlags |= MB_PREPLACED; } - if ((pmap[*x][*y].flags & (HAS_PLAYER | HAS_STAIRS)) - || (monst->bookkeepingFlags & MB_PREPLACED)) { + if ((pmap[*x][*y].flags & (HAS_PLAYER | HAS_STAIRS)) || (monst->bookkeepingFlags & MB_PREPLACED)) { if (!(monst->bookkeepingFlags & MB_PREPLACED)) { // (If if it's preplaced, it won't have set the HAS_MONSTER flag in the first place, // so clearing it might screw up an existing monster.) pmap[*x][*y].flags &= ~HAS_MONSTER; } - getQualifyingPathLocNear(x, y, *x, *y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)), 0, - avoidedFlagsForMonster(&(monst->info)), (HAS_MONSTER | HAS_PLAYER | HAS_STAIRS), true); + getQualifyingPathLocNear(x, y, *x, *y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)), 0, avoidedFlagsForMonster(&(monst->info)), (HAS_MONSTER | HAS_PLAYER | HAS_STAIRS), true); } pmap[*x][*y].flags |= HAS_MONSTER; monst->bookkeepingFlags &= ~(MB_PREPLACED | MB_APPROACHING_DOWNSTAIRS | MB_APPROACHING_UPSTAIRS | MB_APPROACHING_PIT | MB_ABSORBING); @@ -3532,9 +3380,7 @@ void restoreItem(item *theItem) { pos loc; // Items can fall into deep water, enclaved lakes, another chasm, even lava! - getQualifyingLocNear(&loc, theItem->loc.x, theItem->loc.y, true, 0, - (T_OBSTRUCTS_ITEMS), - (HAS_MONSTER | HAS_ITEM | HAS_STAIRS), false, false); + getQualifyingLocNear(&loc, theItem->loc.x, theItem->loc.y, true, 0, (T_OBSTRUCTS_ITEMS), (HAS_MONSTER | HAS_ITEM | HAS_STAIRS), false, false); theItem->loc = loc; } @@ -3544,8 +3390,9 @@ void restoreItem(item *theItem) { } } -// Returns true iff the location is a plain wall, three of the four cardinal neighbors are walls, the remaining cardinal neighbor -// is not a pathing blocker, the two diagonals between the three cardinal walls are also walls, and none of the eight neighbors are in machines. +// Returns true iff the location is a plain wall, three of the four cardinal neighbors are walls, the remaining cardinal +// neighbor is not a pathing blocker, the two diagonals between the three cardinal walls are also walls, and none of the +// eight neighbors are in machines. boolean validStairLoc(short x, short y) { short newX, newY, dir, neighborWallCount; @@ -3553,7 +3400,7 @@ boolean validStairLoc(short x, short y) { return false; } - for (dir=0; dir< DIRECTION_COUNT; dir++) { + for (dir = 0; dir < DIRECTION_COUNT; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; if (pmap[newX][newY].flags & IS_IN_MACHINE) { @@ -3562,7 +3409,7 @@ boolean validStairLoc(short x, short y) { } neighborWallCount = 0; - for (dir=0; dir<4; dir++) { + for (dir = 0; dir < 4; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; @@ -3571,8 +3418,7 @@ boolean validStairLoc(short x, short y) { neighborWallCount++; } else { // neighbor is not a wall - if (cellHasTerrainFlag(newX, newY, T_PATHING_BLOCKER) - || passableArcCount(newX, newY) >= 2) { + if (cellHasTerrainFlag(newX, newY, T_PATHING_BLOCKER) || passableArcCount(newX, newY) >= 2) { return false; } // now check the two diagonals between the walls @@ -3596,13 +3442,13 @@ boolean validStairLoc(short x, short y) { return true; } -// The walls on either side become torches. Any adjacent granite then becomes top_wall. All wall neighbors are un-tunnelable. -// Grid is zeroed out within 5 spaces in all directions. +// The walls on either side become torches. Any adjacent granite then becomes top_wall. All wall neighbors are +// un-tunnelable. Grid is zeroed out within 5 spaces in all directions. void prepareForStairs(short x, short y, char grid[DCOLS][DROWS]) { short newX, newY, dir; // Add torches to either side. - for (dir=0; dir<4; dir++) { + for (dir = 0; dir < 4; dir++) { if (!cellHasTerrainFlag(x + nbDirs[dir][0], y + nbDirs[dir][1], T_OBSTRUCTS_PASSABILITY)) { newX = x - nbDirs[dir][1]; newY = y - nbDirs[dir][0]; @@ -3614,7 +3460,7 @@ void prepareForStairs(short x, short y, char grid[DCOLS][DROWS]) { } } // Expose granite. - for (dir=0; dir< DIRECTION_COUNT; dir++) { + for (dir = 0; dir < DIRECTION_COUNT; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; if (pmap[newX][newY].layers[DUNGEON] == GRANITE) { @@ -3642,8 +3488,8 @@ void initializeLevel() { // Place the stairs. - for (int i=0; i < DCOLS; i++) { - for (int j=0; j < DROWS; j++) { + for (int i = 0; i < DCOLS; i++) { + for (int j = 0; j < DROWS; j++) { grid[i][j] = validStairLoc(i, j); } } @@ -3658,8 +3504,7 @@ void initializeLevel() { if (getQualifyingGridLocNear(&downLoc, levels[n].downStairsLoc.x, levels[n].downStairsLoc.y, grid, false)) { prepareForStairs(downLoc.x, downLoc.y, grid); } else { - getQualifyingLocNear(&downLoc, levels[n].downStairsLoc.x, levels[n].downStairsLoc.y, false, 0, - (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_ITEMS | T_AUTO_DESCENT | T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_IS_DF_TRAP), + getQualifyingLocNear(&downLoc, levels[n].downStairsLoc.x, levels[n].downStairsLoc.y, false, 0, (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_ITEMS | T_AUTO_DESCENT | T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_IS_DF_TRAP), (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), true, false); } @@ -3668,11 +3513,11 @@ void initializeLevel() { } else { pmapAt(downLoc)->layers[DUNGEON] = DOWN_STAIRS; } - pmapAt(downLoc)->layers[LIQUID] = NOTHING; - pmapAt(downLoc)->layers[SURFACE] = NOTHING; + pmapAt(downLoc)->layers[LIQUID] = NOTHING; + pmapAt(downLoc)->layers[SURFACE] = NOTHING; - if (!levels[n+1].visited) { - levels[n+1].upStairsLoc = downLoc; + if (!levels[n + 1].visited) { + levels[n + 1].upStairsLoc = downLoc; } levels[n].downStairsLoc = downLoc; @@ -3680,8 +3525,7 @@ void initializeLevel() { if (getQualifyingGridLocNear(&upLoc, levels[n].upStairsLoc.x, levels[n].upStairsLoc.y, grid, false)) { prepareForStairs(upLoc.x, upLoc.y, grid); } else { // Hopefully this never happens. - getQualifyingLocNear(&upLoc, levels[n].upStairsLoc.x, levels[n].upStairsLoc.y, false, 0, - (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_ITEMS | T_AUTO_DESCENT | T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_IS_DF_TRAP), + getQualifyingLocNear(&upLoc, levels[n].upStairsLoc.x, levels[n].upStairsLoc.y, false, 0, (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_ITEMS | T_AUTO_DESCENT | T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_IS_DF_TRAP), (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), true, false); } @@ -3700,10 +3544,10 @@ void initializeLevel() { rogue.upLoc = upLoc; pmapAt(upLoc)->flags |= HAS_STAIRS; - if (!levels[rogue.depthLevel-1].visited) { + if (!levels[rogue.depthLevel - 1].visited) { // Run a field of view check from up stairs so that monsters do not spawn within sight of it. - for (dir=0; dir<4; dir++) { + for (dir = 0; dir < 4; dir++) { pos nextLoc = posNeighborInDirection(upLoc, dir); if (isPosInMap(nextLoc) && !cellHasTerrainFlag(nextLoc.x, nextLoc.y, T_OBSTRUCTS_PASSABILITY)) { upLoc = nextLoc; @@ -3712,8 +3556,8 @@ void initializeLevel() { } zeroOutGrid(grid); getFOVMask(grid, upLoc.x, upLoc.y, max(DCOLS, DROWS) * FP_FACTOR, (T_OBSTRUCTS_VISION), 0, false); - for (i=0; i= 0 && !cellHasTerrainType(*x, *y, terrainType)) - || (((dungeonType >= 0 && pmap[*x][*y].layers[DUNGEON] != dungeonType) || (liquidType >= 0 && pmap[*x][*y].layers[LIQUID] != liquidType)) && terrainType < 0) - || (pmap[*x][*y].flags & (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS | HAS_ITEM | IS_IN_MACHINE)) - || (terrainType < 0 && !(tileCatalog[dungeonType].flags & T_OBSTRUCTS_ITEMS) - && cellHasTerrainFlag(*x, *y, T_OBSTRUCTS_ITEMS)))); + } while (failsafeCount < 500 + && ((terrainType >= 0 && !cellHasTerrainType(*x, *y, terrainType)) || (((dungeonType >= 0 && pmap[*x][*y].layers[DUNGEON] != dungeonType) || (liquidType >= 0 && pmap[*x][*y].layers[LIQUID] != liquidType)) && terrainType < 0) + || (pmap[*x][*y].flags & (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS | HAS_ITEM | IS_IN_MACHINE)) || (terrainType < 0 && !(tileCatalog[dungeonType].flags & T_OBSTRUCTS_ITEMS) && cellHasTerrainFlag(*x, *y, T_OBSTRUCTS_ITEMS)))); if (failsafeCount >= 500) { return false; } diff --git a/src/brogue/Buttons.c b/src/brogue/Buttons.c index 35b49ffe..58ba59bd 100644 --- a/src/brogue/Buttons.c +++ b/src/brogue/Buttons.c @@ -29,9 +29,7 @@ // Draws the smooth gradient that appears on a button when you hover over or depress it. // Returns the percentage by which the current tile should be averaged toward a hilite color. -short smoothHiliteGradient(const short currentXValue, const short maxXValue) { - return (short) (100 * sin(3.14159265 * currentXValue / maxXValue)); -} +short smoothHiliteGradient(const short currentXValue, const short maxXValue) { return (short)(100 * sin(3.14159265 * currentXValue / maxXValue)); } // Draws the button to the screen, or to a display buffer if one is given. // Button back color fades from -50% intensity at the edges to the back color in the middle. @@ -42,7 +40,7 @@ void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDispl if (!(button->flags & B_DRAW)) { return; } - //assureCosmeticRNG; + // assureCosmeticRNG; short oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; @@ -51,20 +49,20 @@ void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDispl color fColorBase = ((button->flags & B_ENABLED) ? white : gray); if (highlight == BUTTON_HOVER && (button->flags & B_HOVER_ENABLED)) { - //applyColorAugment(&fColorBase, &buttonHoverColor, 20); - //applyColorAugment(&bColorBase, &buttonHoverColor, 20); + // applyColorAugment(&fColorBase, &buttonHoverColor, 20); + // applyColorAugment(&bColorBase, &buttonHoverColor, 20); applyColorAverage(&fColorBase, &buttonHoverColor, 25); applyColorAverage(&bColorBase, &buttonHoverColor, 25); } - color bColorEdge = bColorBase; - color bColorMid = bColorBase; + color bColorEdge = bColorBase; + color bColorMid = bColorBase; applyColorAverage(&bColorEdge, &black, 50); if (highlight == BUTTON_PRESSED) { applyColorAverage(&bColorMid, &black, 75); if (COLOR_DIFF(bColorMid, bColorBase) < 50) { - bColorMid = bColorBase; + bColorMid = bColorBase; applyColorAverage(&bColorMid, &buttonHoverColor, 50); } } @@ -110,8 +108,8 @@ void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDispl symbolNumber++; } - if (locIsInWindow((windowpos){ button->x + i, button->y })) { - plotCharToBuffer(displayCharacter, (windowpos){ button->x + i, button->y }, &fColor, &bColor, dbuf); + if (locIsInWindow((windowpos){button->x + i, button->y})) { + plotCharToBuffer(displayCharacter, (windowpos){button->x + i, button->y}, &fColor, &bColor, dbuf); if (dbuf) { // Only buffers can have opacity set. dbuf[button->x + i][button->y].opacity = opacity; @@ -122,7 +120,7 @@ void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDispl } void initializeButton(brogueButton *button) { - memset((void *) button, 0, sizeof( brogueButton )); + memset((void *)button, 0, sizeof(brogueButton)); button->text[0] = '\0'; button->flags |= (B_ENABLED | B_GRADIENT | B_HOVER_ENABLED | B_DRAW | B_KEYPRESS_HIGHLIGHT); button->buttonColor = interfaceButtonColor; @@ -131,28 +129,22 @@ void initializeButton(brogueButton *button) { void drawButtonsInState(buttonState *state) { // Draw the buttons to the dbuf: - for (int i=0; i < state->buttonCount; i++) { + for (int i = 0; i < state->buttonCount; i++) { if (state->buttons[i].flags & B_DRAW) { drawButton(&(state->buttons[i]), BUTTON_NORMAL, state->dbuf); } } } -void initializeButtonState(buttonState *state, - brogueButton *buttons, - short buttonCount, - short winX, - short winY, - short winWidth, - short winHeight) { +void initializeButtonState(buttonState *state, brogueButton *buttons, short buttonCount, short winX, short winY, short winWidth, short winHeight) { // Initialize variables for the state struct: state->buttonChosen = state->buttonFocused = state->buttonDepressed = -1; - state->buttonCount = buttonCount; - state->winX = winX; - state->winY = winY; - state->winWidth = winWidth; - state->winHeight = winHeight; - for (int i=0; i < state->buttonCount; i++) { + state->buttonCount = buttonCount; + state->winX = winX; + state->winY = winY; + state->winWidth = winWidth; + state->winHeight = winHeight; + for (int i = 0; i < state->buttonCount; i++) { state->buttons[i] = buttons[i]; } copyDisplayBuffer(state->rbuf, displayBuffer); @@ -161,8 +153,8 @@ void initializeButtonState(buttonState *state, drawButtonsInState(state); // Clear the rbuf so that it resets only those parts of the screen in which buttons are drawn in the first place: - for (int i=0; irbuf[i][j].opacity = (state->dbuf[i][j].opacity ? 100 : 0); } } @@ -180,9 +172,7 @@ short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *even boolean buttonUsed = false; // Mouse event: - if (event->eventType == MOUSE_DOWN - || event->eventType == MOUSE_UP - || event->eventType == MOUSE_ENTERED_CELL) { + if (event->eventType == MOUSE_DOWN || event->eventType == MOUSE_UP || event->eventType == MOUSE_ENTERED_CELL) { int x = event->param1; int y = event->param2; @@ -195,11 +185,9 @@ short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *even // Find the button with new focus, if any. int focusIndex; - for (focusIndex=0; focusIndex < state->buttonCount; focusIndex++) { - if ((state->buttons[focusIndex].flags & B_DRAW) - && (state->buttons[focusIndex].flags & B_ENABLED) - && (state->buttons[focusIndex].y == y || ((state->buttons[focusIndex].flags & B_WIDE_CLICK_AREA) && abs(state->buttons[focusIndex].y - y) <= 1)) - && x >= state->buttons[focusIndex].x + for (focusIndex = 0; focusIndex < state->buttonCount; focusIndex++) { + if ((state->buttons[focusIndex].flags & B_DRAW) && (state->buttons[focusIndex].flags & B_ENABLED) + && (state->buttons[focusIndex].y == y || ((state->buttons[focusIndex].flags & B_WIDE_CLICK_AREA) && abs(state->buttons[focusIndex].y - y) <= 1)) && x >= state->buttons[focusIndex].x && x < state->buttons[focusIndex].x + strLenWithoutEscapes(state->buttons[focusIndex].text)) { state->buttonFocused = focusIndex; @@ -231,8 +219,7 @@ short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *even // Otherwise, no button is depressed. If one was previously depressed, redraw it. if (state->buttonDepressed >= 0) { drawButton(&(state->buttons[state->buttonDepressed]), BUTTON_NORMAL, state->dbuf); - } else if (!(x >= state->winX && x < state->winX + state->winWidth - && y >= state->winY && y < state->winY + state->winHeight)) { + } else if (!(x >= state->winX && x < state->winX + state->winWidth && y >= state->winY && y < state->winY + state->winHeight)) { // Clicking outside of a button means canceling. if (canceled) { *canceled = true; @@ -252,7 +239,7 @@ short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *even if (event->eventType == KEYSTROKE) { // Cycle through all of the hotkeys of all of the buttons. - for (int i=0; i < state->buttonCount; i++) { + for (int i = 0; i < state->buttonCount; i++) { for (int k = 0; k < 10 && state->buttons[i].hotkey[k]; k++) { if (event->param1 == state->buttons[i].hotkey[k]) { // This button was chosen. @@ -292,8 +279,7 @@ short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *even } } - if (!buttonUsed - && (event->param1 == ESCAPE_KEY || event->param1 == ACKNOWLEDGE_KEY)) { + if (!buttonUsed && (event->param1 == ESCAPE_KEY || event->param1 == ACKNOWLEDGE_KEY)) { // If the player pressed escape, we're done. if (canceled) { *canceled = true; @@ -313,13 +299,7 @@ short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *even // Returns the index number of the chosen button, or -1 if the user cancels. // A window region is described by winX, winY, winWidth and winHeight. // Clicking outside of that region will constitute canceling. -short buttonInputLoop(brogueButton *buttons, - short buttonCount, - short winX, - short winY, - short winWidth, - short winHeight, - rogueEvent *returnEvent) { +short buttonInputLoop(brogueButton *buttons, short buttonCount, short winX, short winY, short winWidth, short winHeight, rogueEvent *returnEvent) { short button; boolean canceled; rogueEvent theEvent; @@ -349,7 +329,7 @@ short buttonInputLoop(brogueButton *buttons, *returnEvent = theEvent; } - //overlayDisplayBuffer(dbuf, NULL); // hangs around + // overlayDisplayBuffer(dbuf, NULL); // hangs around restoreRNG; diff --git a/src/brogue/Combat.c b/src/brogue/Combat.c index 4383729a..2ea2145f 100644 --- a/src/brogue/Combat.c +++ b/src/brogue/Combat.c @@ -25,7 +25,6 @@ #include "GlobalsBase.h" #include "Globals.h" - /* Combat rules: * Each combatant has an accuracy rating. This is the percentage of their attacks that will ordinarily hit; * higher numbers are better for them. Numbers over 100 are permitted. @@ -50,8 +49,8 @@ * 0-10 with CF 4 would be 2d3 + 2d2. By playing with the numbers, one can approximate a gaussian * distribution of any mean and standard deviation. * - * Player combatants take their base defense value of their actual armor. Their accuracy is a combination of weapon, armor - * and strength. + * Player combatants take their base defense value of their actual armor. Their accuracy is a combination of weapon, + * armor and strength. * * Players have a base accuracy value of 100 throughout the game. Each point of weapon enchantment (net of * strength penalty/benefit) increases @@ -62,7 +61,7 @@ fixpt strengthModifier(item *theItem) { if (difference > 0) { return difference * FP_FACTOR / 4; // 0.25x } else { - return difference * FP_FACTOR * 5/2; // 2.5x + return difference * FP_FACTOR * 5 / 2; // 2.5x } } @@ -80,7 +79,7 @@ fixpt monsterDamageAdjustmentAmount(const creature *monst) { // Handled through player strength routines elsewhere. return FP_FACTOR; } else { - return damageFraction(monst->weaknessAmount * FP_FACTOR * -3/2); + return damageFraction(monst->weaknessAmount * FP_FACTOR * -3 / 2); } } @@ -96,7 +95,7 @@ short monsterDefenseAdjusted(const creature *monst) { } short monsterAccuracyAdjusted(const creature *monst) { - short retval = monst->info.accuracy * accuracyFraction(monst->weaknessAmount * FP_FACTOR * -3/2) / FP_FACTOR; + short retval = monst->info.accuracy * accuracyFraction(monst->weaknessAmount * FP_FACTOR * -3 / 2) / FP_FACTOR; return max(retval, 0); } @@ -110,15 +109,12 @@ short hitProbability(creature *attacker, creature *defender) { if (defender->status[STATUS_STUCK] || (defender->bookkeepingFlags & MB_CAPTIVE)) { return 100; } - if ((defender->bookkeepingFlags & MB_SEIZED) - && (attacker->bookkeepingFlags & MB_SEIZING)) { + if ((defender->bookkeepingFlags & MB_SEIZED) && (attacker->bookkeepingFlags & MB_SEIZING)) { return 100; } if (attacker == &player && rogue.weapon) { - if ((rogue.weapon->flags & ITEM_RUNIC) - && rogue.weapon->enchant2 == W_SLAYING - && monsterIsInClass(defender, rogue.weapon->vorpalEnemy)) { + if ((rogue.weapon->flags & ITEM_RUNIC) && rogue.weapon->enchant2 == W_SLAYING && monsterIsInClass(defender, rogue.weapon->vorpalEnemy)) { return 100; } @@ -135,9 +131,7 @@ short hitProbability(creature *attacker, creature *defender) { boolean attackHit(creature *attacker, creature *defender) { // automatically hit if the monster is sleeping or captive or stuck in a web - if (defender->status[STATUS_STUCK] - || defender->status[STATUS_PARALYZED] - || (defender->bookkeepingFlags & MB_CAPTIVE)) { + if (defender->status[STATUS_STUCK] || defender->status[STATUS_PARALYZED] || (defender->bookkeepingFlags & MB_CAPTIVE)) { return true; } @@ -151,12 +145,12 @@ void addMonsterToContiguousMonsterGrid(short x, short y, creature *monst, char g creature *tempMonst; grid[x][y] = true; - for (dir=0; dir<4; dir++) { + for (dir = 0; dir < 4; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; if (coordinatesAreInMap(newX, newY) && !grid[newX][newY]) { - tempMonst = monsterAtLoc((pos){ newX, newY }); + tempMonst = monsterAtLoc((pos){newX, newY}); if (tempMonst && monstersAreTeammates(monst, tempMonst)) { addMonsterToContiguousMonsterGrid(newX, newY, monst, grid); } @@ -188,17 +182,13 @@ void splitMonster(creature *monst, pos loc) { addMonsterToContiguousMonsterGrid(monst->loc.x, monst->loc.y, monst, monsterGrid); // Find the eligible edges around the group of monsters. - for (int i=0; imutationIndex >= 0) { - clone->info.flags &= (monsterCatalog[clone->info.monsterID].flags | mutationCatalog[monst->mutationIndex].monsterFlags); - clone->info.abilityFlags &= (monsterCatalog[clone->info.monsterID].abilityFlags | mutationCatalog[monst->mutationIndex].monsterAbilityFlags); + clone->info.flags &= (monsterCatalog[clone->info.monsterID].flags | mutationCatalog[monst->mutationIndex].monsterFlags); + clone->info.abilityFlags &= (monsterCatalog[clone->info.monsterID].abilityFlags | mutationCatalog[monst->mutationIndex].monsterAbilityFlags); } else { - clone->info.flags &= monsterCatalog[clone->info.monsterID].flags; - clone->info.abilityFlags &= monsterCatalog[clone->info.monsterID].abilityFlags; + clone->info.flags &= monsterCatalog[clone->info.monsterID].flags; + clone->info.abilityFlags &= monsterCatalog[clone->info.monsterID].abilityFlags; } for (int b = 0; b < 20; b++) { clone->info.bolts[b] = monsterCatalog[clone->info.monsterID].bolts[b]; } - if (!(clone->info.flags & MONST_FLIES) - && clone->status[STATUS_LEVITATING] == 1000) { + if (!(clone->info.flags & MONST_FLIES) && clone->status[STATUS_LEVITATING] == 1000) { clone->status[STATUS_LEVITATING] = 0; } @@ -268,9 +257,7 @@ short alliedCloneCount(creature *monst) { short count = 0; for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *temp = nextCreature(&it); - if (temp != monst - && temp->info.monsterID == monst->info.monsterID - && monstersAreTeammates(temp, monst)) { + if (temp != monst && temp->info.monsterID == monst->info.monsterID && monstersAreTeammates(temp, monst)) { count++; } @@ -278,9 +265,7 @@ short alliedCloneCount(creature *monst) { if (rogue.depthLevel > 1) { for (creatureIterator it = iterateCreatures(&levels[rogue.depthLevel - 2].monsters); hasNextCreature(it);) { creature *temp = nextCreature(&it); - if (temp != monst - && temp->info.monsterID == monst->info.monsterID - && monstersAreTeammates(temp, monst)) { + if (temp != monst && temp->info.monsterID == monst->info.monsterID && monstersAreTeammates(temp, monst)) { count++; } @@ -289,9 +274,7 @@ short alliedCloneCount(creature *monst) { if (rogue.depthLevel < gameConst->deepestLevel) { for (creatureIterator it = iterateCreatures(&levels[rogue.depthLevel].monsters); hasNextCreature(it);) { creature *temp = nextCreature(&it); - if (temp != monst - && temp->info.monsterID == monst->info.monsterID - && monstersAreTeammates(temp, monst)) { + if (temp != monst && temp->info.monsterID == monst->info.monsterID && monstersAreTeammates(temp, monst)) { count++; } @@ -311,12 +294,11 @@ void moralAttack(creature *attacker, creature *defender) { } } - if (defender->currentHP > 0 - && !(defender->bookkeepingFlags & MB_IS_DYING)) { + if (defender->currentHP > 0 && !(defender->bookkeepingFlags & MB_IS_DYING)) { if (defender->status[STATUS_PARALYZED]) { defender->status[STATUS_PARALYZED] = 0; - // Paralyzed creature gets a turn to react before the attacker moves again. + // Paralyzed creature gets a turn to react before the attacker moves again. defender->ticksUntilTurn = min(attacker->attackSpeed, 100) - 1; } if (defender->status[STATUS_MAGICAL_FEAR]) { @@ -328,18 +310,12 @@ void moralAttack(creature *attacker, creature *defender) { defender->status[STATUS_ENRAGED] = defender->maxStatus[STATUS_ENRAGED] = 4; } - if (attacker == &player - && defender->creatureState == MONSTER_ALLY - && !defender->status[STATUS_DISCORDANT] - && !attacker->status[STATUS_CONFUSED] - && !(attacker->bookkeepingFlags & MB_IS_DYING)) { + if (attacker == &player && defender->creatureState == MONSTER_ALLY && !defender->status[STATUS_DISCORDANT] && !attacker->status[STATUS_CONFUSED] && !(attacker->bookkeepingFlags & MB_IS_DYING)) { unAlly(defender); } - if ((attacker == &player || attacker->creatureState == MONSTER_ALLY) - && defender != &player - && defender->creatureState != MONSTER_ALLY) { + if ((attacker == &player || attacker->creatureState == MONSTER_ALLY) && defender != &player && defender->creatureState != MONSTER_ALLY) { alertMonster(defender); // this alerts the monster that you're nearby } @@ -355,11 +331,7 @@ void moralAttack(creature *attacker, creature *defender) { } boolean playerImmuneToMonster(creature *monst) { - if (monst != &player - && rogue.armor - && (rogue.armor->flags & ITEM_RUNIC) - && (rogue.armor->enchant2 == A_IMMUNITY) - && monsterIsInClass(monst, rogue.armor->vorpalEnemy)) { + if (monst != &player && rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && (rogue.armor->enchant2 == A_IMMUNITY) && monsterIsInClass(monst, rogue.armor->vorpalEnemy)) { return true; } else { @@ -382,11 +354,7 @@ void specialHit(creature *attacker, creature *defender, short damage) { return; } - if (attacker->info.abilityFlags & MA_HIT_DEGRADE_ARMOR - && defender == &player - && rogue.armor - && !(rogue.armor->flags & ITEM_PROTECTED) - && (rogue.armor->enchant1 + rogue.armor->armor/10 > -10)) { + if (attacker->info.abilityFlags & MA_HIT_DEGRADE_ARMOR && defender == &player && rogue.armor && !(rogue.armor->flags & ITEM_PROTECTED) && (rogue.armor->enchant1 + rogue.armor->armor / 10 > -10)) { rogue.armor->enchant1--; equipItem(rogue.armor, true, NULL); @@ -405,17 +373,12 @@ void specialHit(creature *attacker, creature *defender, short damage) { player.status[STATUS_HALLUCINATING] += gameConst->onHitHallucinateDuration; player.maxStatus[STATUS_HALLUCINATING] = max(player.maxStatus[STATUS_HALLUCINATING], player.status[STATUS_HALLUCINATING]); } - if (attacker->info.abilityFlags & MA_HIT_BURN - && !defender->status[STATUS_IMMUNE_TO_FIRE]) { + if (attacker->info.abilityFlags & MA_HIT_BURN && !defender->status[STATUS_IMMUNE_TO_FIRE]) { exposeCreatureToFire(defender); } - if (attacker->info.abilityFlags & MA_HIT_STEAL_FLEE - && !(attacker->carriedItem) - && (packItems->nextItem) - && attacker->currentHP > 0 - && !attacker->status[STATUS_CONFUSED] // No stealing from the player if you bump him while confused. + if (attacker->info.abilityFlags & MA_HIT_STEAL_FLEE && !(attacker->carriedItem) && (packItems->nextItem) && attacker->currentHP > 0 && !attacker->status[STATUS_CONFUSED] // No stealing from the player if you bump him while confused. && attackHit(attacker, defender)) { itemCandidates = numberOfMatchingPackItems(ALL_ITEMS, 0, (ITEM_EQUIPPED), false); @@ -466,15 +429,11 @@ void specialHit(creature *attacker, creature *defender, short damage) { } } } - if ((attacker->info.abilityFlags & MA_POISONS) - && damage > 0 - && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { + if ((attacker->info.abilityFlags & MA_POISONS) && damage > 0 && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { addPoison(defender, damage, 1); } - if ((attacker->info.abilityFlags & MA_CAUSES_WEAKNESS) - && damage > 0 - && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { + if ((attacker->info.abilityFlags & MA_CAUSES_WEAKNESS) && damage > 0 && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { weaken(defender, gameConst->onHitWeakenDuration); } @@ -485,7 +444,7 @@ void specialHit(creature *attacker, creature *defender, short damage) { boolean forceWeaponHit(creature *defender, item *theItem) { short forceDamage; - char buf[DCOLS*3], buf2[COLS], monstName[DCOLS]; + char buf[DCOLS * 3], buf2[COLS], monstName[DCOLS]; creature *otherMonster = NULL; boolean knowFirstMonsterDied = false, autoID = false; bolt theBolt; @@ -493,13 +452,8 @@ boolean forceWeaponHit(creature *defender, item *theItem) { monsterName(monstName, defender, true); pos oldLoc = defender->loc; - pos newLoc = (pos){ - .x = defender->loc.x + clamp(defender->loc.x - player.loc.x, -1, 1), - .y = defender->loc.y + clamp(defender->loc.y - player.loc.y, -1, 1) - }; - if (canDirectlySeeMonster(defender) - && !cellHasTerrainFlag(newLoc.x, newLoc.y, T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION) - && !(pmapAt(newLoc)->flags & (HAS_MONSTER | HAS_PLAYER))) { + pos newLoc = (pos){.x = defender->loc.x + clamp(defender->loc.x - player.loc.x, -1, 1), .y = defender->loc.y + clamp(defender->loc.y - player.loc.y, -1, 1)}; + if (canDirectlySeeMonster(defender) && !cellHasTerrainFlag(newLoc.x, newLoc.y, T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION) && !(pmapAt(newLoc)->flags & (HAS_MONSTER | HAS_PLAYER))) { sprintf(buf, "you launch %s backward with the force of your blow", monstName); buf[DCOLS] = '\0'; combatMessage(buf, messageColorFromVictim(defender)); @@ -508,29 +462,25 @@ boolean forceWeaponHit(creature *defender, item *theItem) { theBolt = boltCatalog[BOLT_BLINKING]; theBolt.magnitude = max(1, netEnchant(theItem) / FP_FACTOR); zap(oldLoc, newLoc, &theBolt, false, false); - if (!(defender->bookkeepingFlags & MB_IS_DYING) - && distanceBetween(oldLoc, defender->loc) > 0 - && distanceBetween(oldLoc, defender->loc) < weaponForceDistance(netEnchant(theItem))) { + if (!(defender->bookkeepingFlags & MB_IS_DYING) && distanceBetween(oldLoc, defender->loc) > 0 && distanceBetween(oldLoc, defender->loc) < weaponForceDistance(netEnchant(theItem))) { if (pmap[defender->loc.x + newLoc.x - oldLoc.x][defender->loc.y + newLoc.y - oldLoc.y].flags & (HAS_MONSTER | HAS_PLAYER)) { - otherMonster = monsterAtLoc((pos){ defender->loc.x + newLoc.x - oldLoc.x, defender->loc.y + newLoc.y - oldLoc.y }); + otherMonster = monsterAtLoc((pos){defender->loc.x + newLoc.x - oldLoc.x, defender->loc.y + newLoc.y - oldLoc.y}); monsterName(buf2, otherMonster, true); } else { otherMonster = NULL; - strcpy(buf2, tileCatalog[pmap[defender->loc.x + newLoc.x - oldLoc.x][defender->loc.y + newLoc.y - oldLoc.y].layers[highestPriorityLayer(defender->loc.x + newLoc.x - oldLoc.x, defender->loc.y + newLoc.y - oldLoc.y, true)]].description); + strcpy( + buf2, + tileCatalog[pmap[defender->loc.x + newLoc.x - oldLoc.x][defender->loc.y + newLoc.y - oldLoc.y].layers[highestPriorityLayer(defender->loc.x + newLoc.x - oldLoc.x, defender->loc.y + newLoc.y - oldLoc.y, true)]].description); } forceDamage = distanceBetween(oldLoc, defender->loc); - if (!(defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) - && inflictDamage(NULL, defender, forceDamage, &white, false)) { + if (!(defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) && inflictDamage(NULL, defender, forceDamage, &white, false)) { if (canDirectlySeeMonster(defender)) { knowFirstMonsterDied = true; - sprintf(buf, "%s %s on impact with %s", - monstName, - (defender->info.flags & MONST_INANIMATE) ? "is destroyed" : "dies", - buf2); + sprintf(buf, "%s %s on impact with %s", monstName, (defender->info.flags & MONST_INANIMATE) ? "is destroyed" : "dies", buf2); buf[DCOLS] = '\0'; combatMessage(buf, messageColorFromVictim(defender)); autoID = true; @@ -538,9 +488,7 @@ boolean forceWeaponHit(creature *defender, item *theItem) { killCreature(defender, false); } else { if (canDirectlySeeMonster(defender)) { - sprintf(buf, "%s slams against %s", - monstName, - buf2); + sprintf(buf, "%s slams against %s", monstName, buf2); buf[DCOLS] = '\0'; combatMessage(buf, messageColorFromVictim(defender)); autoID = true; @@ -548,16 +496,11 @@ boolean forceWeaponHit(creature *defender, item *theItem) { } moralAttack(&player, defender); - if (otherMonster - && !(defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE))) { + if (otherMonster && !(defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE))) { if (inflictDamage(NULL, otherMonster, forceDamage, &white, false)) { if (canDirectlySeeMonster(otherMonster)) { - sprintf(buf, "%s %s%s when %s slams into $HIMHER", - buf2, - (knowFirstMonsterDied ? "also " : ""), - (defender->info.flags & MONST_INANIMATE) ? "is destroyed" : "dies", - monstName); + sprintf(buf, "%s %s%s when %s slams into $HIMHER", buf2, (knowFirstMonsterDied ? "also " : ""), (defender->info.flags & MONST_INANIMATE) ? "is destroyed" : "dies", monstName); resolvePronounEscapes(buf, otherMonster); buf[DCOLS] = '\0'; combatMessage(buf, messageColorFromVictim(otherMonster)); @@ -575,10 +518,9 @@ boolean forceWeaponHit(creature *defender, item *theItem) { } void magicWeaponHit(creature *defender, item *theItem, boolean backstabbed) { - char buf[DCOLS*3], monstName[DCOLS], theItemName[DCOLS]; + char buf[DCOLS * 3], monstName[DCOLS], theItemName[DCOLS]; - const color *effectColors[NUMBER_WEAPON_RUNIC_KINDS] = {&white, &black, - &yellow, &pink, &green, &confusionGasColor, NULL, NULL, &darkRed, &rainbow}; + const color *effectColors[NUMBER_WEAPON_RUNIC_KINDS] = {&white, &black, &yellow, &pink, &green, &confusionGasColor, NULL, NULL, &darkRed, &rainbow}; // W_SPEED, W_QUIETUS, W_PARALYSIS, W_MULTIPLICITY, W_SLOWING, W_CONFUSION, W_FORCE, W_SLAYING, W_MERCY, W_PLENTY short chance, i; fixpt enchant; @@ -588,9 +530,7 @@ void magicWeaponHit(creature *defender, item *theItem, boolean backstabbed) { // If the defender is already dead, proceed only if the runic is speed or multiplicity. // (Everything else acts on the victim, which would literally be overkill.) - if ((defender->bookkeepingFlags & MB_IS_DYING) - && theItem->enchant2 != W_SPEED - && theItem->enchant2 != W_MULTIPLICITY) { + if ((defender->bookkeepingFlags & MB_IS_DYING) && theItem->enchant2 != W_SPEED && theItem->enchant2 != W_MULTIPLICITY) { return; } @@ -641,9 +581,7 @@ void magicWeaponHit(creature *defender, item *theItem, boolean backstabbed) { case W_SLAYING: case W_QUIETUS: inflictLethalDamage(&player, defender); - sprintf(buf, "%s suddenly %s", - monstName, - (defender->info.flags & MONST_INANIMATE) ? "shatters" : "dies"); + sprintf(buf, "%s suddenly %s", monstName, (defender->info.flags & MONST_INANIMATE) ? "shatters" : "dies"); buf[DCOLS] = '\0'; combatMessage(buf, messageColorFromVictim(defender)); killCreature(defender, false); @@ -660,18 +598,14 @@ void magicWeaponHit(creature *defender, item *theItem, boolean backstabbed) { } break; case W_MULTIPLICITY: - sprintf(buf, "Your %s emits a flash of light, and %sspectral duplicate%s appear%s!", - theItemName, - (weaponImageCount(enchant) == 1 ? "a " : ""), - (weaponImageCount(enchant) == 1 ? "" : "s"), + sprintf(buf, "Your %s emits a flash of light, and %sspectral duplicate%s appear%s!", theItemName, (weaponImageCount(enchant) == 1 ? "a " : ""), (weaponImageCount(enchant) == 1 ? "" : "s"), (weaponImageCount(enchant) == 1 ? "s" : "")); buf[DCOLS] = '\0'; for (i = 0; i < (weaponImageCount(enchant)); i++) { newMonst = generateMonster(MK_SPECTRAL_IMAGE, true, false); - getQualifyingPathLocNear(&(newMonst->loc.x), &(newMonst->loc.y), defender->loc.x, defender->loc.y, true, - T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(newMonst->info)), HAS_PLAYER, - avoidedFlagsForMonster(&(newMonst->info)), (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); + getQualifyingPathLocNear(&(newMonst->loc.x), &(newMonst->loc.y), defender->loc.x, defender->loc.y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(newMonst->info)), HAS_PLAYER, avoidedFlagsForMonster(&(newMonst->info)), + (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); newMonst->bookkeepingFlags |= (MB_FOLLOWER | MB_BOUND_TO_LEADER | MB_DOES_NOT_TRACK_LEADER | MB_TELEPATHICALLY_REVEALED); newMonst->bookkeepingFlags &= ~MB_JUST_SUMMONED; newMonst->leader = &player; @@ -784,7 +718,8 @@ void attackVerb(char returnString[DCOLS], creature *attacker, short hitPercentil return; } - for (verbCount = 0; verbCount < 4 && monsterText[attacker->info.monsterID].attack[verbCount + 1][0] != '\0'; verbCount++); + for (verbCount = 0; verbCount < 4 && monsterText[attacker->info.monsterID].attack[verbCount + 1][0] != '\0'; verbCount++) + ; increment = (100 / (verbCount + 1)); hitPercentile = max(0, min(hitPercentile, increment * (verbCount + 1) - 1)); strcpy(returnString, monsterText[attacker->info.monsterID].attack[hitPercentile / increment]); @@ -860,18 +795,14 @@ void applyArmorRunicEffect(char returnString[DCOLS], creature *attacker, short * case A_MUTUALITY: if (*damage > 0) { count = 0; - for (i=0; i<8; i++) { + for (i = 0; i < 8; i++) { hitList[i] = NULL; dir = i % 8; newX = player.loc.x + nbDirs[dir][0]; newY = player.loc.y + nbDirs[dir][1]; if (coordinatesAreInMap(newX, newY) && (pmap[newX][newY].flags & HAS_MONSTER)) { - monst = monsterAtLoc((pos){ newX, newY }); - if (monst - && monst != attacker - && monstersAreEnemies(&player, monst) - && !(monst->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) - && !(monst->bookkeepingFlags & MB_IS_DYING)) { + monst = monsterAtLoc((pos){newX, newY}); + if (monst && monst != attacker && monstersAreEnemies(&player, monst) && !(monst->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) && !(monst->bookkeepingFlags & MB_IS_DYING)) { hitList[i] = monst; count++; @@ -879,7 +810,7 @@ void applyArmorRunicEffect(char returnString[DCOLS], creature *attacker, short * } } if (count) { - for (i=0; i<8; i++) { + for (i = 0; i < 8; i++) { if (hitList[i] && !(hitList[i]->bookkeepingFlags & MB_IS_DYING)) { monsterName(monstName, hitList[i], true); if (inflictDamage(&player, hitList[i], (*damage + count) / (count + 1), &blue, true)) { @@ -893,9 +824,7 @@ void applyArmorRunicEffect(char returnString[DCOLS], creature *attacker, short * } runicDiscovered = true; if (!runicKnown) { - sprintf(returnString, "Your %s pulses, and the damage is shared with %s!", - armorName, - (count == 1 ? monstName : "the other adjacent enemies")); + sprintf(returnString, "Your %s pulses, and the damage is shared with %s!", armorName, (count == 1 ? monstName : "the other adjacent enemies")); } *damage = (*damage + count) / (count + 1); } @@ -967,11 +896,9 @@ void applyArmorRunicEffect(char returnString[DCOLS], creature *attacker, short * } void decrementWeaponAutoIDTimer() { - char buf[COLS*3], buf2[COLS*3]; + char buf[COLS * 3], buf2[COLS * 3]; - if (rogue.weapon - && !(rogue.weapon->flags & ITEM_IDENTIFIED) - && !--rogue.weapon->charges) { + if (rogue.weapon && !(rogue.weapon->flags & ITEM_IDENTIFIED) && !--rogue.weapon->charges) { rogue.weapon->flags |= ITEM_IDENTIFIED; updateIdentifiableItems(); @@ -983,17 +910,13 @@ void decrementWeaponAutoIDTimer() { } void processStaggerHit(creature *attacker, creature *defender) { - if ((defender->info.flags & (MONST_INVULNERABLE | MONST_IMMOBILE | MONST_INANIMATE)) - || (defender->bookkeepingFlags & MB_CAPTIVE) - || cellHasTerrainFlag(defender->loc.x, defender->loc.y, T_OBSTRUCTS_PASSABILITY)) { + if ((defender->info.flags & (MONST_INVULNERABLE | MONST_IMMOBILE | MONST_INANIMATE)) || (defender->bookkeepingFlags & MB_CAPTIVE) || cellHasTerrainFlag(defender->loc.x, defender->loc.y, T_OBSTRUCTS_PASSABILITY)) { return; } short newX = clamp(defender->loc.x - attacker->loc.x, -1, 1) + defender->loc.x; short newY = clamp(defender->loc.y - attacker->loc.y, -1, 1) + defender->loc.y; - if (coordinatesAreInMap(newX, newY) - && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) - && !(pmap[newX][newY].flags & (HAS_MONSTER | HAS_PLAYER))) { + if (coordinatesAreInMap(newX, newY) && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) && !(pmap[newX][newY].flags & (HAS_MONSTER | HAS_PLAYER))) { setMonsterLocation(defender, newX, newY); } @@ -1002,7 +925,7 @@ void processStaggerHit(creature *attacker, creature *defender) { // returns whether the attack hit boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { short damage, specialDamage, poisonDamage; - char buf[COLS*2], buf2[COLS*2], attackerName[COLS], defenderName[COLS], verb[DCOLS], explicationClause[DCOLS] = "", armorRunicString[DCOLS*3]; + char buf[COLS * 2], buf2[COLS * 2], attackerName[COLS], defenderName[COLS], verb[DCOLS], explicationClause[DCOLS] = "", armorRunicString[DCOLS * 3]; boolean sneakAttack, defenderWasAsleep, defenderWasParalyzed, degradesAttackerWeapon, sightUnseen; if (attacker == &player && canSeeMonster(defender)) { @@ -1035,8 +958,7 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { defender->status[STATUS_MAGICAL_FEAR] = 1; } - if (attacker == &player - && defender->creatureState != MONSTER_TRACKING_SCENT) { + if (attacker == &player && defender->creatureState != MONSTER_TRACKING_SCENT) { rogue.featRecord[FEAT_PALADIN] = false; } @@ -1058,10 +980,8 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { monsterName(attackerName, attacker, true); monsterName(defenderName, defender, true); - if ((attacker->info.abilityFlags & MA_SEIZES) - && (!(attacker->bookkeepingFlags & MB_SEIZING) || !(defender->bookkeepingFlags & MB_SEIZED)) - && (distanceBetween(attacker->loc, defender->loc) == 1 - && !diagonalBlocked(attacker->loc.x, attacker->loc.y, defender->loc.x, defender->loc.y, false))) { + if ((attacker->info.abilityFlags & MA_SEIZES) && (!(attacker->bookkeepingFlags & MB_SEIZING) || !(defender->bookkeepingFlags & MB_SEIZED)) + && (distanceBetween(attacker->loc, defender->loc) == 1 && !diagonalBlocked(attacker->loc.x, attacker->loc.y, defender->loc.x, defender->loc.y, false))) { attacker->bookkeepingFlags |= MB_SEIZING; defender->bookkeepingFlags |= MB_SEIZED; @@ -1074,8 +994,7 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { if (sneakAttack || defenderWasAsleep || defenderWasParalyzed || lungeAttack || attackHit(attacker, defender)) { // If the attack hit: - damage = (defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE) - ? 0 : randClump(attacker->info.damage) * monsterDamageAdjustmentAmount(attacker) / FP_FACTOR); + damage = (defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE) ? 0 : randClump(attacker->info.damage) * monsterDamageAdjustmentAmount(attacker) / FP_FACTOR); if (sneakAttack || defenderWasAsleep || defenderWasParalyzed) { if (defender != &player) { @@ -1087,9 +1006,7 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { } } if (sneakAttack || defenderWasAsleep || defenderWasParalyzed || lungeAttack) { - if (attacker == &player - && rogue.weapon - && (rogue.weapon->flags & ITEM_SNEAK_ATTACK_BONUS)) { + if (attacker == &player && rogue.weapon && (rogue.weapon->flags & ITEM_SNEAK_ATTACK_BONUS)) { damage *= 5; // 5x damage for dagger sneak attacks. } else { @@ -1101,9 +1018,7 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { applyArmorRunicEffect(armorRunicString, attacker, &damage, true); } - if (attacker == &player - && rogue.reaping - && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { + if (attacker == &player && rogue.reaping && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { specialDamage = min(damage, defender->currentHP) * rogue.reaping; // Maximum reaped damage can't exceed the victim's remaining health. if (rogue.reaping > 0) { @@ -1130,9 +1045,7 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { } else if (sneakAttack) { strcpy(explicationClause, ", catching $HIMHER unaware"); } else if (defender->status[STATUS_STUCK] || defender->bookkeepingFlags & MB_CAPTIVE) { - sprintf(explicationClause, " while %s dangle%s helplessly", - (canSeeMonster(defender) ? "$HESHE" : "it"), - (defender == &player ? "" : "s")); + sprintf(explicationClause, " while %s dangle%s helplessly", (canSeeMonster(defender) ? "$HESHE" : "it"), (defender == &player ? "" : "s")); } resolvePronounEscapes(explicationClause, defender); @@ -1143,16 +1056,9 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { if (inflictDamage(attacker, defender, damage, &red, false)) { // if the attack killed the defender if (defenderWasAsleep || sneakAttack || defenderWasParalyzed || lungeAttack) { - sprintf(buf, "%s %s %s%s", attackerName, - ((defender->info.flags & MONST_INANIMATE) ? "destroyed" : "dispatched"), - defenderName, - explicationClause); + sprintf(buf, "%s %s %s%s", attackerName, ((defender->info.flags & MONST_INANIMATE) ? "destroyed" : "dispatched"), defenderName, explicationClause); } else { - sprintf(buf, "%s %s %s%s", - attackerName, - ((defender->info.flags & MONST_INANIMATE) ? "destroyed" : "defeated"), - defenderName, - explicationClause); + sprintf(buf, "%s %s %s%s", attackerName, ((defender->info.flags & MONST_INANIMATE) ? "destroyed" : "defeated"), defenderName, explicationClause); } if (sightUnseen) { if (defender->info.flags & MONST_INANIMATE) { @@ -1167,15 +1073,15 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { if (&player == defender) { gameOver(attacker->info.monsterName, false); return true; - } else if (&player == attacker - && defender->info.monsterID == MK_DRAGON) { + } else if (&player == attacker && defender->info.monsterID == MK_DRAGON) { rogue.featRecord[FEAT_DRAGONSLAYER] = true; } } else { // if the defender survived if (!rogue.blockCombatText && (canSeeMonster(attacker) || canSeeMonster(defender))) { - attackVerb(verb, attacker, max(damage - (attacker->info.damage.lowerBound * monsterDamageAdjustmentAmount(attacker) / FP_FACTOR), 0) * 100 - / max(1, (attacker->info.damage.upperBound - attacker->info.damage.lowerBound) * monsterDamageAdjustmentAmount(attacker) / FP_FACTOR)); + attackVerb(verb, attacker, + max(damage - (attacker->info.damage.lowerBound * monsterDamageAdjustmentAmount(attacker) / FP_FACTOR), 0) * 100 + / max(1, (attacker->info.damage.upperBound - attacker->info.damage.lowerBound) * monsterDamageAdjustmentAmount(attacker) / FP_FACTOR)); sprintf(buf, "%s %s %s%s", attackerName, verb, defenderName, explicationClause); if (sightUnseen) { if (!rogue.heardCombatThisTurn) { @@ -1206,20 +1112,15 @@ boolean attack(creature *attacker, creature *defender, boolean lungeAttack) { magicWeaponHit(defender, rogue.weapon, sneakAttack || defenderWasAsleep || defenderWasParalyzed); } - if (attacker == &player - && (defender->bookkeepingFlags & MB_IS_DYING) - && (defender->bookkeepingFlags & MB_HAS_SOUL)) { + if (attacker == &player && (defender->bookkeepingFlags & MB_IS_DYING) && (defender->bookkeepingFlags & MB_HAS_SOUL)) { decrementWeaponAutoIDTimer(); } - if (degradesAttackerWeapon - && attacker == &player - && rogue.weapon + if (degradesAttackerWeapon && attacker == &player && rogue.weapon && !(rogue.weapon->flags & ITEM_PROTECTED) - // Can't damage a Weapon of Acid Mound Slaying by attacking an acid mound... just ain't right! - && !((rogue.weapon->flags & ITEM_RUNIC) && rogue.weapon->enchant2 == W_SLAYING && monsterIsInClass(defender, rogue.weapon->vorpalEnemy)) - && rogue.weapon->enchant1 >= -10) { + // Can't damage a Weapon of Acid Mound Slaying by attacking an acid mound... just ain't right! + && !((rogue.weapon->flags & ITEM_RUNIC) && rogue.weapon->enchant2 == W_SLAYING && monsterIsInClass(defender, rogue.weapon->vorpalEnemy)) && rogue.weapon->enchant1 >= -10) { rogue.weapon->enchant1--; if (rogue.weapon->quiverNumber) { @@ -1254,7 +1155,7 @@ short strLenWithoutEscapes(const char *str) { short i, count; count = 0; - for (i=0; str[i];) { + for (i = 0; str[i];) { if (str[i] == COLOR_ESCAPE) { i += 4; continue; @@ -1344,11 +1245,7 @@ void flashMonster(creature *monst, const color *theColor, short strength) { boolean canAbsorb(creature *ally, boolean ourBolts[], creature *prey, short **grid) { short i; - if (ally->creatureState == MONSTER_ALLY - && ally->newPowerCount > 0 - && (!isPosInMap(ally->targetCorpseLoc)) - && !((ally->info.flags | prey->info.flags) & (MONST_INANIMATE | MONST_IMMOBILE)) - && !monsterAvoids(ally, prey->loc) + if (ally->creatureState == MONSTER_ALLY && ally->newPowerCount > 0 && (!isPosInMap(ally->targetCorpseLoc)) && !((ally->info.flags | prey->info.flags) & (MONST_INANIMATE | MONST_IMMOBILE)) && !monsterAvoids(ally, prey->loc) && grid[ally->loc.x][ally->loc.y] <= 10) { if (~(ally->info.abilityFlags) & prey->info.abilityFlags & LEARNABLE_ABILITIES) { @@ -1363,9 +1260,8 @@ boolean canAbsorb(creature *ally, boolean ourBolts[], creature *prey, short **gr ourBolts[ally->info.bolts[i]] = true; } - for (i=0; prey->info.bolts[i] != BOLT_NONE; i++) { - if (!(boltCatalog[prey->info.bolts[i]].flags & BF_NOT_LEARNABLE) - && !ourBolts[prey->info.bolts[i]]) { + for (i = 0; prey->info.bolts[i] != BOLT_NONE; i++) { + if (!(boltCatalog[prey->info.bolts[i]].flags & BF_NOT_LEARNABLE) && !ourBolts[prey->info.bolts[i]]) { return true; } @@ -1380,16 +1276,12 @@ boolean anyoneWantABite(creature *decedent) { short **grid; boolean success = false; boolean *ourBolts; - + ourBolts = (boolean *)calloc(gameConst->numberBoltKinds, sizeof(boolean)); candidates = 0; - if ((!(decedent->info.abilityFlags & LEARNABLE_ABILITIES) - && !(decedent->info.flags & LEARNABLE_BEHAVIORS) - && decedent->info.bolts[0] == BOLT_NONE) - || (cellHasTerrainFlag(decedent->loc.x, decedent->loc.y, T_PATHING_BLOCKER)) - || decedent->info.monsterID == MK_SPECTRAL_IMAGE - || (decedent->info.flags & (MONST_INANIMATE | MONST_IMMOBILE))) { + if ((!(decedent->info.abilityFlags & LEARNABLE_ABILITIES) && !(decedent->info.flags & LEARNABLE_BEHAVIORS) && decedent->info.bolts[0] == BOLT_NONE) || (cellHasTerrainFlag(decedent->loc.x, decedent->loc.y, T_PATHING_BLOCKER)) + || decedent->info.monsterID == MK_SPECTRAL_IMAGE || (decedent->info.flags & (MONST_INANIMATE | MONST_IMMOBILE))) { return false; } @@ -1422,21 +1314,20 @@ boolean anyoneWantABite(creature *decedent) { // Choose a superpower. // First, select from among learnable ability or behavior flags, if one is available. candidates = 0; - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) { if (Fl(i) & ~(firstAlly->info.abilityFlags) & decedent->info.abilityFlags & LEARNABLE_ABILITIES) { candidates++; } } - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) { if (Fl(i) & ~(firstAlly->info.flags) & decedent->info.flags & LEARNABLE_BEHAVIORS) { candidates++; } } if (candidates > 0) { randIndex = rand_range(1, candidates); - for (i=0; i<32; i++) { - if ((Fl(i) & ~(firstAlly->info.abilityFlags) & decedent->info.abilityFlags & LEARNABLE_ABILITIES) - && !--randIndex) { + for (i = 0; i < 32; i++) { + if ((Fl(i) & ~(firstAlly->info.abilityFlags) & decedent->info.abilityFlags & LEARNABLE_ABILITIES) && !--randIndex) { firstAlly->absorptionFlags = Fl(i); firstAlly->absorbBehavior = false; @@ -1444,9 +1335,8 @@ boolean anyoneWantABite(creature *decedent) { break; } } - for (i=0; i<32 && !success; i++) { - if ((Fl(i) & ~(firstAlly->info.flags) & decedent->info.flags & LEARNABLE_BEHAVIORS) - && !--randIndex) { + for (i = 0; i < 32 && !success; i++) { + if ((Fl(i) & ~(firstAlly->info.flags) & decedent->info.flags & LEARNABLE_BEHAVIORS) && !--randIndex) { firstAlly->absorptionFlags = Fl(i); firstAlly->absorbBehavior = true; @@ -1457,19 +1347,16 @@ boolean anyoneWantABite(creature *decedent) { } else if (decedent->info.bolts[0] != BOLT_NONE) { // If there are no learnable ability or behavior flags, pick a learnable bolt. candidates = 0; - for (i=0; decedent->info.bolts[i] != BOLT_NONE; i++) { - if (!(boltCatalog[decedent->info.bolts[i]].flags & BF_NOT_LEARNABLE) - && !ourBolts[decedent->info.bolts[i]]) { + for (i = 0; decedent->info.bolts[i] != BOLT_NONE; i++) { + if (!(boltCatalog[decedent->info.bolts[i]].flags & BF_NOT_LEARNABLE) && !ourBolts[decedent->info.bolts[i]]) { candidates++; } } if (candidates > 0) { randIndex = rand_range(1, candidates); - for (i=0; decedent->info.bolts[i] != BOLT_NONE; i++) { - if (!(boltCatalog[decedent->info.bolts[i]].flags & BF_NOT_LEARNABLE) - && !ourBolts[decedent->info.bolts[i]] - && !--randIndex) { + for (i = 0; decedent->info.bolts[i] != BOLT_NONE; i++) { + if (!(boltCatalog[decedent->info.bolts[i]].flags & BF_NOT_LEARNABLE) && !ourBolts[decedent->info.bolts[i]] && !--randIndex) { firstAlly->absorptionBolt = decedent->info.bolts[i]; success = true; @@ -1485,27 +1372,22 @@ boolean anyoneWantABite(creature *decedent) { return success; } -#define MIN_FLASH_STRENGTH 50 +#define MIN_FLASH_STRENGTH 50 -void inflictLethalDamage(creature *attacker, creature *defender) { - inflictDamage(attacker, defender, defender->currentHP, NULL, true); -} +void inflictLethalDamage(creature *attacker, creature *defender) { inflictDamage(attacker, defender, defender->currentHP, NULL, true); } // returns true if this was a killing stroke; does NOT call killCreature // flashColor indicates the color that the damage will cause the creature to flash -boolean inflictDamage(creature *attacker, creature *defender, - short damage, const color *flashColor, boolean ignoresProtectionShield) { +boolean inflictDamage(creature *attacker, creature *defender, short damage, const color *flashColor, boolean ignoresProtectionShield) { dungeonFeature theBlood; short transferenceAmount; - if (damage == 0 - || (defender->info.flags & MONST_INVULNERABLE)) { + if (damage == 0 || (defender->info.flags & MONST_INVULNERABLE)) { return false; } - if (!ignoresProtectionShield - && defender->status[STATUS_SHIELDED]) { + if (!ignoresProtectionShield && defender->status[STATUS_SHIELDED]) { if (defender->status[STATUS_SHIELDED] > damage * 10) { defender->status[STATUS_SHIELDED] -= damage * 10; @@ -1532,14 +1414,11 @@ boolean inflictDamage(creature *attacker, creature *defender, wakeUp(defender); } - if (defender == &player - && rogue.easyMode - && damage > 0) { - damage = max(1, damage/5); + if (defender == &player && rogue.easyMode && damage > 0) { + damage = max(1, damage / 5); } - if (((attacker == &player && rogue.transference) || (attacker && attacker != &player && (attacker->info.abilityFlags & MA_TRANSFERENCE))) - && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { + if (((attacker == &player && rogue.transference) || (attacker && attacker != &player && (attacker->info.abilityFlags & MA_TRANSFERENCE))) && !(defender->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { transferenceAmount = min(damage, defender->currentHP); // Maximum transferred damage can't exceed the victim's remaining health. @@ -1574,9 +1453,7 @@ boolean inflictDamage(creature *attacker, creature *defender, } } - if (defender != &player && defender->creatureState != MONSTER_ALLY - && defender->info.flags & MONST_FLEES_NEAR_DEATH - && defender->info.maxHP / 4 >= defender->currentHP) { + if (defender != &player && defender->creatureState != MONSTER_ALLY && defender->info.flags & MONST_FLEES_NEAR_DEATH && defender->info.maxHP / 4 >= defender->currentHP) { defender->creatureState = MONSTER_FLEEING; } @@ -1611,11 +1488,11 @@ void addPoison(creature *monst, short durationIncrement, short concentrationIncr } } - // Marks the decedent as dying, but does not remove it from the monster chain to avoid iterator invalidation; // that is done in `removeDeadMonsters`. -// Use "administrativeDeath" if the monster is being deleted for administrative purposes, as opposed to dying as a result of physical actions. -// AdministrativeDeath means the monster simply disappears, with no messages, dropped item, DFs or other effect. +// Use "administrativeDeath" if the monster is being deleted for administrative purposes, as opposed to dying as a +// result of physical actions. AdministrativeDeath means the monster simply disappears, with no messages, dropped item, +// DFs or other effect. void killCreature(creature *decedent, boolean administrativeDeath) { short x, y; char monstName[DCOLS], buf[DCOLS * 3]; @@ -1645,8 +1522,7 @@ void killCreature(creature *decedent, boolean administrativeDeath) { } } - if (!administrativeDeath && (decedent->info.abilityFlags & MA_DF_ON_DEATH) - && !(decedent->bookkeepingFlags & MB_IS_FALLING)) { + if (!administrativeDeath && (decedent->info.abilityFlags & MA_DF_ON_DEATH) && !(decedent->bookkeepingFlags & MB_IS_FALLING)) { spawnDungeonFeature(decedent->loc.x, decedent->loc.y, &dungeonFeatureCatalog[decedent->info.DFType], true, false); if (monsterText[decedent->info.monsterID].DFMessage[0] && canSeeMonster(decedent)) { @@ -1660,12 +1536,7 @@ void killCreature(creature *decedent, boolean administrativeDeath) { if (decedent == &player) { // the player died // game over handled elsewhere } else { - if (!administrativeDeath - && decedent->creatureState == MONSTER_ALLY - && !canSeeMonster(decedent) - && !(decedent->info.flags & MONST_INANIMATE) - && !(decedent->bookkeepingFlags & MB_BOUND_TO_LEADER) - && !decedent->carriedMonster) { + if (!administrativeDeath && decedent->creatureState == MONSTER_ALLY && !canSeeMonster(decedent) && !(decedent->info.flags & MONST_INANIMATE) && !(decedent->bookkeepingFlags & MB_BOUND_TO_LEADER) && !decedent->carriedMonster) { messageWithColor("you feel a sense of loss.", &badMessageColor, 0); } @@ -1728,8 +1599,7 @@ void buildHitList(creature **hitList, const creature *attacker, creature *defend dir = NO_DIRECTION; for (i = 0; i < DIRECTION_COUNT; i++) { - if (nbDirs[i][0] == newX - x - && nbDirs[i][1] == newY - y) { + if (nbDirs[i][0] == newX - x && nbDirs[i][1] == newY - y) { dir = i; break; @@ -1740,15 +1610,13 @@ void buildHitList(creature **hitList, const creature *attacker, creature *defend if (dir == NO_DIRECTION) { dir = UP; // Just pick one. } - for (i=0; i<8; i++) { + for (i = 0; i < 8; i++) { newDir = (dir + i) % DIRECTION_COUNT; newestX = x + cDirs[newDir][0]; newestY = y + cDirs[newDir][1]; if (coordinatesAreInMap(newestX, newestY) && (pmap[newestX][newestY].flags & (HAS_MONSTER | HAS_PLAYER))) { - defender = monsterAtLoc((pos){ newestX, newestY }); - if (defender - && monsterWillAttackTarget(attacker, defender) - && (!cellHasTerrainFlag(defender->loc.x, defender->loc.y, T_OBSTRUCTS_PASSABILITY) || (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS))) { + defender = monsterAtLoc((pos){newestX, newestY}); + if (defender && monsterWillAttackTarget(attacker, defender) && (!cellHasTerrainFlag(defender->loc.x, defender->loc.y, T_OBSTRUCTS_PASSABILITY) || (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS))) { hitList[i] = defender; } diff --git a/src/brogue/Dijkstra.c b/src/brogue/Dijkstra.c index a9f07d15..68361f07 100644 --- a/src/brogue/Dijkstra.c +++ b/src/brogue/Dijkstra.c @@ -92,7 +92,7 @@ static void pdsUpdate(pdsMap *map, boolean useDiagonals) { static void pdsClear(pdsMap *map, short maxDistance) { map->front.right = NULL; - for (int i=0; i < DCOLS*DROWS; i++) { + for (int i = 0; i < DCOLS * DROWS; i++) { map->links[i].distance = maxDistance; map->links[i].left = NULL; map->links[i].right = NULL; @@ -129,8 +129,8 @@ static void pdsBatchInput(pdsMap *map, short **distanceMap, short **costMap, sho pdsLink *right = NULL; map->front.right = NULL; - for (int i=0; idistance; } } @@ -206,32 +208,21 @@ void dijkstraScan(short **distanceMap, short **costMap, boolean useDiagonals) { pdsBatchOutput(&map, distanceMap, useDiagonals); } -void calculateDistances(short **distanceMap, - short destinationX, short destinationY, - unsigned long blockingTerrainFlags, - creature *traveler, - boolean canUseSecretDoors, - boolean eightWays) { +void calculateDistances(short **distanceMap, short destinationX, short destinationY, unsigned long blockingTerrainFlags, creature *traveler, boolean canUseSecretDoors, boolean eightWays) { static pdsMap map; - for (int i=0; iinfo.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) - && (monst->info.flags & (MONST_IMMOBILE | MONST_GETS_TURN_ON_ACTIVATION))) { + creature *monst = monsterAtLoc((pos){i, j}); + if (monst && (monst->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) && (monst->info.flags & (MONST_IMMOBILE | MONST_GETS_TURN_ON_ACTIVATION))) { // Always avoid damage-immune stationary monsters. cost = PDS_FORBIDDEN; - } else if (canUseSecretDoors - && cellHasTMFlag(i, j, TM_IS_SECRET) - && cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) - && !(discoveredTerrainFlagsAtLoc(i, j) & T_OBSTRUCTS_PASSABILITY)) { + } else if (canUseSecretDoors && cellHasTMFlag(i, j, TM_IS_SECRET) && cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) && !(discoveredTerrainFlagsAtLoc(i, j) & T_OBSTRUCTS_PASSABILITY)) { cost = 1; - } else if (cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) - || (traveler && traveler == &player && !(pmap[i][j].flags & (DISCOVERED | MAGIC_MAPPED)))) { + } else if (cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) || (traveler && traveler == &player && !(pmap[i][j].flags & (DISCOVERED | MAGIC_MAPPED)))) { cost = cellHasTerrainFlag(i, j, T_OBSTRUCTS_DIAGONAL_MOVEMENT) ? PDS_OBSTRUCTION : PDS_FORBIDDEN; } else if ((traveler && monsterAvoids(traveler, (pos){i, j})) || cellHasTerrainFlag(i, j, blockingTerrainFlags)) { @@ -256,4 +247,3 @@ short pathingDistance(short x1, short y1, short x2, short y2, unsigned long bloc freeGrid(distanceMap); return retval; } - diff --git a/src/brogue/Globals.h b/src/brogue/Globals.h index 8bdf54c9..cc24c56f 100644 --- a/src/brogue/Globals.h +++ b/src/brogue/Globals.h @@ -31,7 +31,7 @@ extern const color deepWaterLightColor; extern const color confusionGasColor; -extern color minersLightColor; //dynamic +extern color minersLightColor; // dynamic extern const color basicLightColor; extern const color torchLightColor; diff --git a/src/brogue/GlobalsBase.c b/src/brogue/GlobalsBase.c index 49a7f2fb..e2cbf3b3 100644 --- a/src/brogue/GlobalsBase.c +++ b/src/brogue/GlobalsBase.c @@ -27,15 +27,15 @@ #include "Rogue.h" -tcell tmap[DCOLS][DROWS]; // grids with info about the map +tcell tmap[DCOLS][DROWS]; // grids with info about the map pcell pmap[DCOLS][DROWS]; short **scentMap; -cellDisplayBuffer displayBuffer[COLS][ROWS]; // used to optimize plotCharWithColor +cellDisplayBuffer displayBuffer[COLS][ROWS]; // used to optimize plotCharWithColor short terrainRandomValues[DCOLS][DROWS][8]; -short **safetyMap; // used to help monsters flee -short **allySafetyMap; // used to help allies flee -short **chokeMap; // used to assess the importance of the map's various chokepoints -const short nbDirs[8][2] = {{0,-1}, {0,1}, {-1,0}, {1,0}, {-1,-1}, {-1,1}, {1,-1}, {1,1}}; +short **safetyMap; // used to help monsters flee +short **allySafetyMap; // used to help allies flee +short **chokeMap; // used to assess the importance of the map's various chokepoints +const short nbDirs[8][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; const short cDirs[8][2] = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}; short numberOfWaypoints; levelData *levels; @@ -50,7 +50,7 @@ item *floorItems; item *packItems; item *monsterItemsHopper; -char displayedMessage[MESSAGE_LINES][COLS*2]; +char displayedMessage[MESSAGE_LINES][COLS * 2]; short messagesUnconfirmed; char combatText[COLS * 2]; short messageArchivePosition; @@ -58,7 +58,7 @@ archivedMessage messageArchive[MESSAGE_ARCHIVE_ENTRIES]; char currentFilePath[BROGUE_FILENAME_MAX]; -char displayDetail[DCOLS][DROWS]; // used to make certain per-cell data accessible to external code (e.g. terminal adaptations) +char displayDetail[DCOLS][DROWS]; // used to make certain per-cell data accessible to external code (e.g. terminal adaptations) #ifdef AUDIT_RNG FILE *RNGLogFile; @@ -71,53 +71,50 @@ unsigned long positionInPlaybackFile; unsigned long lengthOfPlaybackFile; unsigned long recordingLocation; unsigned long maxLevelChanges; -char annotationPathname[BROGUE_FILENAME_MAX]; // pathname of annotation file +char annotationPathname[BROGUE_FILENAME_MAX]; // pathname of annotation file uint64_t previousGameSeed; -const windowpos WINDOW_POSITION_DUNGEON_TOP_LEFT = { STAT_BAR_WIDTH + 3, MESSAGE_LINES + 2}; +const windowpos WINDOW_POSITION_DUNGEON_TOP_LEFT = {STAT_BAR_WIDTH + 3, MESSAGE_LINES + 2}; // Red Green Blue RedRand GreenRand BlueRand Rand Dances? // basic colors -const color white = {100, 100, 100, 0, 0, 0, 0, false}; -const color gray = {50, 50, 50, 0, 0, 0, 0, false}; -const color darkGray = {30, 30, 30, 0, 0, 0, 0, false}; -const color veryDarkGray = {15, 15, 15, 0, 0, 0, 0, false}; -const color black = {0, 0, 0, 0, 0, 0, 0, false}; -const color yellow = {100, 100, 0, 0, 0, 0, 0, false}; -const color darkYellow = {50, 50, 0, 0, 0, 0, 0, false}; -const color teal = {30, 100, 100, 0, 0, 0, 0, false}; -const color purple = {100, 0, 100, 0, 0, 0, 0, false}; -const color darkPurple = {50, 0, 50, 0, 0, 0, 0, false}; -const color brown = {60, 40, 0, 0, 0, 0, 0, false}; -const color green = {0, 100, 0, 0, 0, 0, 0, false}; -const color darkGreen = {0, 50, 0, 0, 0, 0, 0, false}; -const color orange = {100, 50, 0, 0, 0, 0, 0, false}; -const color darkOrange = {50, 25, 0, 0, 0, 0, 0, false}; -const color blue = {0, 0, 100, 0, 0, 0, 0, false}; -const color darkBlue = {0, 0, 50, 0, 0, 0, 0, false}; -const color darkTurquoise = {0, 40, 65, 0, 0, 0, 0, false}; -const color lightBlue = {40, 40, 100, 0, 0, 0, 0, false}; -const color pink = {100, 60, 66, 0, 0, 0, 0, false}; -const color darkPink = {50, 30, 33, 0, 0, 0, 0, false}; -const color red = {100, 0, 0, 0, 0, 0, 0, false}; -const color darkRed = {50, 0, 0, 0, 0, 0, 0, false}; -const color tanColor = {80, 67, 15, 0, 0, 0, 0, false}; +const color white = {100, 100, 100, 0, 0, 0, 0, false}; +const color gray = {50, 50, 50, 0, 0, 0, 0, false}; +const color darkGray = {30, 30, 30, 0, 0, 0, 0, false}; +const color veryDarkGray = {15, 15, 15, 0, 0, 0, 0, false}; +const color black = {0, 0, 0, 0, 0, 0, 0, false}; +const color yellow = {100, 100, 0, 0, 0, 0, 0, false}; +const color darkYellow = {50, 50, 0, 0, 0, 0, 0, false}; +const color teal = {30, 100, 100, 0, 0, 0, 0, false}; +const color purple = {100, 0, 100, 0, 0, 0, 0, false}; +const color darkPurple = {50, 0, 50, 0, 0, 0, 0, false}; +const color brown = {60, 40, 0, 0, 0, 0, 0, false}; +const color green = {0, 100, 0, 0, 0, 0, 0, false}; +const color darkGreen = {0, 50, 0, 0, 0, 0, 0, false}; +const color orange = {100, 50, 0, 0, 0, 0, 0, false}; +const color darkOrange = {50, 25, 0, 0, 0, 0, 0, false}; +const color blue = {0, 0, 100, 0, 0, 0, 0, false}; +const color darkBlue = {0, 0, 50, 0, 0, 0, 0, false}; +const color darkTurquoise = {0, 40, 65, 0, 0, 0, 0, false}; +const color lightBlue = {40, 40, 100, 0, 0, 0, 0, false}; +const color pink = {100, 60, 66, 0, 0, 0, 0, false}; +const color darkPink = {50, 30, 33, 0, 0, 0, 0, false}; +const color red = {100, 0, 0, 0, 0, 0, 0, false}; +const color darkRed = {50, 0, 0, 0, 0, 0, 0, false}; +const color tanColor = {80, 67, 15, 0, 0, 0, 0, false}; // tile colors -const color rainbow = {-70, -70, -70, 170, 170, 170, 0, true}; +const color rainbow = {-70, -70, -70, 170, 170, 170, 0, true}; // charm constants const fixpt POW_0_CHARM_INCREMENT[] = { // 1.0 - 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, - 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, - 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536}; + 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, + 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536}; const fixpt POW_120_CHARM_INCREMENT[] = { // 1.20^x fixed point, with x from 1 to 50 in increments of 1: - 78643, 94371, 113246, 135895, 163074, 195689, 234827, 281792, 338151, 405781, 486937, 584325, 701190, 841428, 1009714, 1211657, - 1453988, 1744786, 2093744, 2512492, 3014991, 3617989, 4341587, 5209905, 6251886, 7502263, 9002716, 10803259, 12963911, 15556694, - 18668032, 22401639, 26881967, 32258360, 38710033, 46452039, 55742447, 66890937, 80269124, 96322949, 115587539, 138705047, 166446056, - 199735268, 239682321, 287618785, 345142543, 414171051, 497005262, 596406314, 715687577}; + 78643, 94371, 113246, 135895, 163074, 195689, 234827, 281792, 338151, 405781, 486937, 584325, 701190, 841428, 1009714, 1211657, 1453988, + 1744786, 2093744, 2512492, 3014991, 3617989, 4341587, 5209905, 6251886, 7502263, 9002716, 10803259, 12963911, 15556694, 18668032, 22401639, 26881967, 32258360, + 38710033, 46452039, 55742447, 66890937, 80269124, 96322949, 115587539, 138705047, 166446056, 199735268, 239682321, 287618785, 345142543, 414171051, 497005262, 596406314, 715687577}; const fixpt POW_125_CHARM_INCREMENT[] = { // 1.25^x fixed point, with x from 1 to 50 in increments of 1: - 81920, 102400, 128000, 160000, 200000, 250000, 312500, 390625, 488281, 610351, 762939, 953674, 1192092, 1490116, 1862645, 2328306, - 2910383, 3637978, 4547473, 5684341, 7105427, 8881784, 11102230, 13877787, 17347234, 21684043, 27105054, 33881317, 42351647, 52939559, - 66174449, 82718061, 103397576, 129246970, 161558713, 201948391, 252435489, 315544362, 394430452, 493038065, 616297582, 770371977, - 962964972, 1203706215, 1504632769, 1880790961, 2350988701, 2938735877, 3673419846, 4591774807, 5739718509}; + 81920, 102400, 128000, 160000, 200000, 250000, 312500, 390625, 488281, 610351, 762939, 953674, 1192092, 1490116, 1862645, 2328306, 2910383, + 3637978, 4547473, 5684341, 7105427, 8881784, 11102230, 13877787, 17347234, 21684043, 27105054, 33881317, 42351647, 52939559, 66174449, 82718061, 103397576, 129246970, + 161558713, 201948391, 252435489, 315544362, 394430452, 493038065, 616297582, 770371977, 962964972, 1203706215, 1504632769, 1880790961, 2350988701, 2938735877, 3673419846, 4591774807, 5739718509}; diff --git a/src/brogue/GlobalsBase.h b/src/brogue/GlobalsBase.h index 4fd4915b..a723649c 100644 --- a/src/brogue/GlobalsBase.h +++ b/src/brogue/GlobalsBase.h @@ -21,19 +21,18 @@ * along with this program. If not, see . */ - -extern tcell tmap[DCOLS][DROWS]; // grids with info about the map -extern pcell pmap[DCOLS][DROWS]; // grids with info about the map +extern tcell tmap[DCOLS][DROWS]; // grids with info about the map +extern pcell pmap[DCOLS][DROWS]; // grids with info about the map // Returns a pointer to the `tcell` at the given position. The position must be in-bounds. -static inline tcell* tmapAt(pos p) { - brogueAssert(p.x >= 0 && p.x < DCOLS && p.y >= 0 && p.y < DROWS); - return &tmap[p.x][p.y]; +static inline tcell *tmapAt(pos p) { + brogueAssert(p.x >= 0 && p.x < DCOLS && p.y >= 0 && p.y < DROWS); + return &tmap[p.x][p.y]; } // Returns a pointer to the `pcell` at the given position. The position must be in-bounds. -static inline pcell* pmapAt(pos p) { - brogueAssert(p.x >= 0 && p.x < DCOLS && p.y >= 0 && p.y < DROWS); - return &pmap[p.x][p.y]; +static inline pcell *pmapAt(pos p) { + brogueAssert(p.x >= 0 && p.x < DCOLS && p.y >= 0 && p.y < DROWS); + return &pmap[p.x][p.y]; } extern const short nbDirs[8][2]; @@ -41,14 +40,14 @@ extern const short nbDirs[8][2]; // Returns the `pos` which is one cell away in the provided direction. // The direction must not be `NO_DIRECTION`. static inline pos posNeighborInDirection(pos p, enum directions direction_to_step) { - brogueAssert(direction_to_step >= 0 && direction_to_step < 8); - return (pos) { .x = p.x + nbDirs[direction_to_step][0], .y = p.y + nbDirs[direction_to_step][1] }; + brogueAssert(direction_to_step >= 0 && direction_to_step < 8); + return (pos){.x = p.x + nbDirs[direction_to_step][0], .y = p.y + nbDirs[direction_to_step][1]}; } extern short **scentMap; extern cellDisplayBuffer displayBuffer[COLS][ROWS]; extern short terrainRandomValues[DCOLS][DROWS][8]; -extern short **safetyMap; // used to help monsters flee +extern short **safetyMap; // used to help monsters flee extern short **allySafetyMap; extern short **chokeMap; @@ -67,9 +66,9 @@ extern item *packItems; extern item *monsterItemsHopper; extern short numberOfWaypoints; -extern char displayedMessage[MESSAGE_LINES][COLS*2]; +extern char displayedMessage[MESSAGE_LINES][COLS * 2]; extern short messagesUnconfirmed; -extern char combatText[COLS*2]; +extern char combatText[COLS * 2]; extern short messageArchivePosition; extern archivedMessage messageArchive[MESSAGE_ARCHIVE_ENTRIES]; @@ -89,7 +88,7 @@ extern unsigned long positionInPlaybackFile; extern unsigned long lengthOfPlaybackFile; extern unsigned long recordingLocation; extern unsigned long maxLevelChanges; -extern char annotationPathname[BROGUE_FILENAME_MAX]; // pathname of annotation file +extern char annotationPathname[BROGUE_FILENAME_MAX]; // pathname of annotation file extern uint64_t previousGameSeed; // basic colors diff --git a/src/brogue/Grid.c b/src/brogue/Grid.c index accce326..6a58e64d 100644 --- a/src/brogue/Grid.c +++ b/src/brogue/Grid.c @@ -25,14 +25,13 @@ #include "Globals.h" #include "GlobalsBase.h" - // mallocing two-dimensional arrays! dun dun DUN! short **allocGrid() { short i; short **array = malloc(DCOLS * sizeof(short *)); array[0] = malloc(DROWS * DCOLS * sizeof(short)); - for(i = 1; i < DCOLS; i++) { + for (i = 1; i < DCOLS; i++) { array[i] = array[0] + i * DROWS; } return array; @@ -46,8 +45,8 @@ void freeGrid(short **array) { void copyGrid(short **to, short **from) { short i, j; - for(i = 0; i < DCOLS; i++) { - for(j = 0; j < DROWS; j++) { + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS; j++) { to[i][j] = from[i][j]; } } @@ -56,14 +55,15 @@ void copyGrid(short **to, short **from) { void fillGrid(short **grid, short fillValue) { short i, j; - for(i = 0; i < DCOLS; i++) { - for(j = 0; j < DROWS; j++) { + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS; j++) { grid[i][j] = fillValue; } } } -// Highlight the portion indicated by hiliteCharGrid with the hiliteColor at the hiliteStrength -- both latter arguments are optional. +// Highlight the portion indicated by hiliteCharGrid with the hiliteColor at the hiliteStrength -- both latter arguments +// are optional. void hiliteGrid(short **grid, const color *hiliteColor, short hiliteStrength) { short i, j, x, y; color hCol; @@ -82,8 +82,8 @@ void hiliteGrid(short **grid, const color *hiliteColor, short hiliteStrength) { hiliteStrength = 75; } - for (i=0; i= findValueMin && grid[i][j] <= findValueMax) { grid[i][j] = fillValue; } @@ -124,9 +124,7 @@ short floodFillGrid(short **grid, short x, short y, short eligibleValueMin, shor for (dir = 0; dir < 4; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && grid[newX][newY] >= eligibleValueMin - && grid[newX][newY] <= eligibleValueMax) { + if (coordinatesAreInMap(newX, newY) && grid[newX][newY] >= eligibleValueMin && grid[newX][newY] <= eligibleValueMax) { fillCount += floodFillGrid(grid, newX, newY, eligibleValueMin, eligibleValueMax, fillValue); } } @@ -136,8 +134,8 @@ short floodFillGrid(short **grid, short x, short y, short eligibleValueMin, shor void drawRectangleOnGrid(short **grid, short x, short y, short width, short height, short value) { short i, j; - for (i=x; i < x+width; i++) { - for (j=y; j= minPassableArc && count <= maxPassableArc) { @@ -229,8 +227,8 @@ void getPassableArcGrid(short **grid, short minPassableArc, short maxPassableArc short validLocationCount(short **grid, short validValue) { short i, j, count; count = 0; - for(i = 0; i < DCOLS; i++) { - for(j = 0; j < DROWS; j++) { + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS; j++) { if (grid[i][j] == validValue) { count++; } @@ -241,8 +239,8 @@ short validLocationCount(short **grid, short validValue) { short leastPositiveValueInGrid(short **grid) { short i, j, leastPositiveValue = 0; - for(i = 0; i < DCOLS; i++) { - for(j = 0; j < DROWS; j++) { + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS; j++) { if (grid[i][j] > 0 && (leastPositiveValue == 0 || grid[i][j] < leastPositiveValue)) { leastPositiveValue = grid[i][j]; } @@ -262,8 +260,8 @@ void randomLocationInGrid(short **grid, short *x, short *y, short validValue) { return; } short index = rand_range(0, locationCount - 1); - for(i = 0; i < DCOLS && index >= 0; i++) { - for(j = 0; j < DROWS && index >= 0; j++) { + for (i = 0; i < DCOLS && index >= 0; i++) { + for (j = 0; j < DROWS && index >= 0; j++) { if (grid[i][j] == validValue) { if (index == 0) { *x = i; @@ -289,8 +287,8 @@ void randomLeastPositiveLocationInGrid(short **grid, short *x, short *y, boolean } locationCount = 0; - for(i = 0; i < DCOLS; i++) { - for(j = 0; j < DROWS; j++) { + for (i = 0; i < DCOLS; i++) { + for (j = 0; j < DROWS; j++) { if (grid[i][j] == targetValue) { locationCount++; } @@ -303,8 +301,8 @@ void randomLeastPositiveLocationInGrid(short **grid, short *x, short *y, boolean index = rand_range(0, locationCount - 1); } - for(i = 0; i < DCOLS && index >= 0; i++) { - for(j = 0; j < DROWS && index >= 0; j++) { + for (i = 0; i < DCOLS && index >= 0; i++) { + for (j = 0; j < DROWS && index >= 0; j++) { if (grid[i][j] == targetValue) { if (index == 0) { *x = i; @@ -317,20 +315,12 @@ void randomLeastPositiveLocationInGrid(short **grid, short *x, short *y, boolean return; } -boolean getQualifyingPathLocNear(short *retValX, short *retValY, - short x, short y, - boolean hallwaysAllowed, - unsigned long blockingTerrainFlags, - unsigned long blockingMapFlags, - unsigned long forbiddenTerrainFlags, - unsigned long forbiddenMapFlags, - boolean deterministic) { +boolean getQualifyingPathLocNear(short *retValX, short *retValY, short x, short y, boolean hallwaysAllowed, unsigned long blockingTerrainFlags, unsigned long blockingMapFlags, unsigned long forbiddenTerrainFlags, + unsigned long forbiddenMapFlags, boolean deterministic) { short **grid, **costMap; // First check the given location to see if it works, as an optimization. - if (!cellHasTerrainFlag(x, y, blockingTerrainFlags | forbiddenTerrainFlags) - && !(pmap[x][y].flags & (blockingMapFlags | forbiddenMapFlags)) - && (hallwaysAllowed || passableArcCount(x, y) <= 1)) { + if (!cellHasTerrainFlag(x, y, blockingTerrainFlags | forbiddenTerrainFlags) && !(pmap[x][y].flags & (blockingMapFlags | forbiddenMapFlags)) && (hallwaysAllowed || passableArcCount(x, y) <= 1)) { *retValX = x; *retValY = y; @@ -366,12 +356,12 @@ boolean getQualifyingPathLocNear(short *retValX, short *retValY, // Get the solution. randomLeastPositiveLocationInGrid(grid, retValX, retValY, deterministic); -// dumpLevelToScreen(); -// displayGrid(grid); -// if (coordinatesAreInMap(*retValX, *retValY)) { -// hiliteCell(*retValX, *retValY, &yellow, 100, true); -// } -// temporaryMessage("Qualifying path selected:", REQUIRE_ACKNOWLEDGMENT); + // dumpLevelToScreen(); + // displayGrid(grid); + // if (coordinatesAreInMap(*retValX, *retValY)) { + // hiliteCell(*retValX, *retValY, &yellow, 100, true); + // } + // temporaryMessage("Qualifying path selected:", REQUIRE_ACKNOWLEDGMENT); freeGrid(grid); freeGrid(costMap); @@ -379,10 +369,7 @@ boolean getQualifyingPathLocNear(short *retValX, short *retValY, // Fall back to a pathing-agnostic alternative if there are no solutions. if (*retValX == -1 && *retValY == -1) { pos loc; - if (getQualifyingLocNear(&loc, x, y, hallwaysAllowed, NULL, - (blockingTerrainFlags | forbiddenTerrainFlags), - (blockingMapFlags | forbiddenMapFlags), - false, deterministic)) { + if (getQualifyingLocNear(&loc, x, y, hallwaysAllowed, NULL, (blockingTerrainFlags | forbiddenTerrainFlags), (blockingMapFlags | forbiddenMapFlags), false, deterministic)) { *retValX = loc.x; *retValY = loc.y; return true; // Found a fallback solution. @@ -402,14 +389,13 @@ void cellularAutomataRound(short **grid, char birthParameters[9], char survivalP buffer2 = allocGrid(); copyGrid(buffer2, grid); // Make a backup of grid in buffer2, so that each generation is isolated. - for(i=0; iflags &= ~IS_IN_PATH; refreshDungeonCell(path[i].x, path[i].y); } } else { - for (int i=0; iflags |= IS_IN_PATH; refreshDungeonCell(path[i].x, path[i].y); @@ -74,8 +75,8 @@ void clearCursorPath() { short i, j; if (!rogue.playbackMode) { // There are no cursor paths during playback. - for (i=1; i= 0 && map[i][j] < 30000) { - const int dist = (i - x)*(i - x) + (j - y)*(j - y); - //hiliteCell(i, j, &purple, min(dist / 2, 100), false); - if (dist < closestDistance - || dist == closestDistance && map[i][j] < lowestMapScore) { + const int dist = (i - x) * (i - x) + (j - y) * (j - y); + // hiliteCell(i, j, &purple, min(dist / 2, 100), false); + if (dist < closestDistance || dist == closestDistance && map[i][j] < lowestMapScore) { - answer = (pos){ i, j }; + answer = (pos){i, j}; closestDistance = dist; lowestMapScore = map[i][j]; } @@ -146,9 +146,7 @@ void processSnapMap(short **map) { for (dir = 0; dir < 4; dir++) { newX = i + nbDirs[dir][0]; newY = j + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && map[newX][newY] >= 0 - && map[newX][newY] < map[i][j]) { + if (coordinatesAreInMap(newX, newY) && map[newX][newY] >= 0 && map[newX][newY] < map[i][j]) { map[i][j] = map[newX][newY]; } @@ -181,7 +179,7 @@ short actionMenu(short x, boolean playingBack) { encodeMessageColor(darkGrayColorEscape, 0, &black); do { - for (i=0; i:%s Next Level ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %s>:%s Next Level ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Next Level "); } @@ -251,7 +249,7 @@ short actionMenu(short x, boolean playingBack) { buttonCount++; } else { if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sZ: %sRest until better ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %sZ: %sRest until better ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Rest until better "); } @@ -259,7 +257,7 @@ short actionMenu(short x, boolean playingBack) { buttonCount++; if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sA: %sAutopilot ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %sA: %sAutopilot ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Autopilot "); } @@ -267,7 +265,7 @@ short actionMenu(short x, boolean playingBack) { buttonCount++; if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sT: %sRe-throw at last monster ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %sT: %sRe-throw at last monster ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Re-throw at last monster "); } @@ -276,7 +274,7 @@ short actionMenu(short x, boolean playingBack) { if (!rogue.easyMode) { if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %s&: %sEasy mode ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %s&: %sEasy mode ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Easy mode "); } @@ -290,9 +288,9 @@ short actionMenu(short x, boolean playingBack) { } if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %s\\: %s[%s] Hide color effects ", yellowColorEscape, whiteColorEscape, rogue.trueColorMode ? "X" : " "); + sprintf(buttons[buttonCount].text, " %s\\: %s[%s] Hide color effects ", yellowColorEscape, whiteColorEscape, rogue.trueColorMode ? "X" : " "); } else { - sprintf(buttons[buttonCount].text, " [%s] Hide color effects ", rogue.trueColorMode ? " " : "X"); + sprintf(buttons[buttonCount].text, " [%s] Hide color effects ", rogue.trueColorMode ? " " : "X"); } buttons[buttonCount].hotkey[0] = TRUE_COLORS_KEY; takeActionOurselves[buttonCount] = true; @@ -300,7 +298,7 @@ short actionMenu(short x, boolean playingBack) { if (KEYBOARD_LABELS) { sprintf(buttons[buttonCount].text, " %s]: %s[%s] Display stealth range ", yellowColorEscape, whiteColorEscape, rogue.displayStealthRangeMode ? "X" : " "); } else { - sprintf(buttons[buttonCount].text, " [%s] Show stealth range ", rogue.displayStealthRangeMode ? "X" : " "); + sprintf(buttons[buttonCount].text, " [%s] Show stealth range ", rogue.displayStealthRangeMode ? "X" : " "); } buttons[buttonCount].hotkey[0] = STEALTH_RANGE_KEY; takeActionOurselves[buttonCount] = true; @@ -310,7 +308,7 @@ short actionMenu(short x, boolean playingBack) { if (KEYBOARD_LABELS) { sprintf(buttons[buttonCount].text, " %sG: %s[%c] Enable graphics ", yellowColorEscape, whiteColorEscape, " X~"[graphicsMode]); } else { - sprintf(buttons[buttonCount].text, " [%c] Enable graphics ", " X~"[graphicsMode]); + sprintf(buttons[buttonCount].text, " [%c] Enable graphics ", " X~"[graphicsMode]); } buttons[buttonCount].hotkey[0] = GRAPHICS_KEY; takeActionOurselves[buttonCount] = true; @@ -322,7 +320,7 @@ short actionMenu(short x, boolean playingBack) { buttonCount++; if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sD: %sDiscovered items ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %sD: %sDiscovered items ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Discovered items "); } @@ -338,7 +336,7 @@ short actionMenu(short x, boolean playingBack) { } buttonCount++; if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %s~: %sView dungeon seed ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %s~: %sView dungeon seed ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " View dungeon seed "); } @@ -355,15 +353,15 @@ short actionMenu(short x, boolean playingBack) { if (!serverMode) { if (playingBack) { - if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sO: %sOpen saved game ", yellowColorEscape, whiteColorEscape); + if (KEYBOARD_LABELS) { + sprintf(buttons[buttonCount].text, " %sO: %sOpen saved game ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Open saved game "); } buttons[buttonCount].hotkey[0] = LOAD_SAVED_GAME_KEY; buttonCount++; if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sV: %sView saved recording ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %sV: %sView saved recording ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " View saved recording "); } @@ -371,7 +369,7 @@ short actionMenu(short x, boolean playingBack) { buttonCount++; } else { if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sS: %sSave and exit ", yellowColorEscape, whiteColorEscape); + sprintf(buttons[buttonCount].text, " %sS: %sSave and exit ", yellowColorEscape, whiteColorEscape); } else { strcpy(buttons[buttonCount].text, " Save and exit "); } @@ -380,9 +378,9 @@ short actionMenu(short x, boolean playingBack) { } } if (KEYBOARD_LABELS) { - sprintf(buttons[buttonCount].text, " %sQ: %sQuit %s ", yellowColorEscape, whiteColorEscape, (playingBack ? "to title screen" : "and abandon game")); + sprintf(buttons[buttonCount].text, " %sQ: %sQuit %s ", yellowColorEscape, whiteColorEscape, (playingBack ? "to title screen" : "and abandon game")); } else { - sprintf(buttons[buttonCount].text, " Quit %s ", (playingBack ? "to title screen" : "and abandon game")); + sprintf(buttons[buttonCount].text, " Quit %s ", (playingBack ? "to title screen" : "and abandon game")); } buttons[buttonCount].hotkey[0] = QUIT_KEY; buttonCount++; @@ -391,14 +389,14 @@ short actionMenu(short x, boolean playingBack) { buttons[buttonCount].flags &= ~B_ENABLED; buttonCount++; - for (i=0; i= COLS) { x = COLS - longestName - 1; } y = ROWS - buttonCount; - for (i=0; ibuttons[i]), BUTTON_NORMAL, state->rbuf); } - for (i=0; irbuf[i][ROWS - 1].backColorComponents); desaturate(&tempColor, 60); applyColorAverage(&tempColor, &black, 50); @@ -537,18 +529,16 @@ void initializeMenuButtons(buttonState *state, brogueButton buttons[5]) { } } - // This is basically the main loop for the game. void mainInputLoop() { - pos oldTargetLoc = { 0, 0 }; + pos oldTargetLoc = {0, 0}; short steps, oldRNG, dir, newX, newY; pos path[1000]; creature *monst; item *theItem; cellDisplayBuffer rbuf[COLS][ROWS]; - boolean canceled, targetConfirmed, tabKey, focusedOnMonster, focusedOnItem, focusedOnTerrain, - playingBack, doEvent, textDisplayed; + boolean canceled, targetConfirmed, tabKey, focusedOnMonster, focusedOnItem, focusedOnTerrain, playingBack, doEvent, textDisplayed; rogueEvent theEvent; short **costMap, **playerPathingMap, **cursorSnapMap; @@ -589,9 +579,7 @@ void mainInputLoop() { temporaryMessage("Examine what? (, mouse, or )", 0); } - if (!playingBack - && posEq(player.loc, rogue.cursorLoc) - && posEq(oldTargetLoc, rogue.cursorLoc)) { + if (!playingBack && posEq(player.loc, rogue.cursorLoc) && posEq(oldTargetLoc, rogue.cursorLoc)) { // Path hides when you reach your destination. rogue.cursorMode = false; @@ -613,19 +601,19 @@ void mainInputLoop() { // Draw the cursor and path if (isPosInMap(oldTargetLoc)) { - refreshDungeonCell(oldTargetLoc.x, oldTargetLoc.y); // Remove old cursor. + refreshDungeonCell(oldTargetLoc.x, oldTargetLoc.y); // Remove old cursor. } if (!playingBack) { if (isPosInMap(oldTargetLoc)) { - hilitePath(path, steps, true); // Unhilite old path. + hilitePath(path, steps, true); // Unhilite old path. } if (isPosInMap(rogue.cursorLoc)) { pos pathDestination; - if (cursorSnapMap[rogue.cursorLoc.x][rogue.cursorLoc.y] >= 0 - && cursorSnapMap[rogue.cursorLoc.x][rogue.cursorLoc.y] < 30000) { + if (cursorSnapMap[rogue.cursorLoc.x][rogue.cursorLoc.y] >= 0 && cursorSnapMap[rogue.cursorLoc.x][rogue.cursorLoc.y] < 30000) { pathDestination = rogue.cursorLoc; } else { - // If the cursor is aimed at an inaccessible area, find the nearest accessible area to path toward. + // If the cursor is aimed at an inaccessible area, find the nearest accessible area to path + // toward. pathDestination = getClosestValidLocationOnMap(cursorSnapMap, rogue.cursorLoc.x, rogue.cursorLoc.y); } @@ -637,30 +625,24 @@ void mainInputLoop() { costMap[pathDestination.x][pathDestination.y] = backupCost; steps = getPlayerPathOnMap(path, playerPathingMap, player.loc); -// steps = getPlayerPathOnMap(path, playerPathingMap, pathDestination[0], pathDestination[1]) - 1; // Get new path. -// reversePath(path, steps); // Flip it around, back-to-front. + // steps = getPlayerPathOnMap(path, playerPathingMap, pathDestination[0], + // pathDestination[1]) - 1; // Get new path. reversePath(path, steps); // Flip it + // around, back-to-front. if (steps >= 0) { path[steps] = pathDestination; } steps++; -// if (playerPathingMap[cursor[0]][cursor[1]] != 1 - if (playerPathingMap[player.loc.x][player.loc.y] != 1 - || !posEq(pathDestination, rogue.cursorLoc)) { + // if (playerPathingMap[cursor[0]][cursor[1]] != 1 + if (playerPathingMap[player.loc.x][player.loc.y] != 1 || !posEq(pathDestination, rogue.cursorLoc)) { - hilitePath(path, steps, false); // Hilite new path. + hilitePath(path, steps, false); // Hilite new path. } } } if (isPosInMap(rogue.cursorLoc)) { - hiliteCell(rogue.cursorLoc.x, - rogue.cursorLoc.y, - &white, - (steps <= 0 - || posEq(path[steps-1], rogue.cursorLoc) - || (!playingBack && distanceBetween(player.loc, rogue.cursorLoc) <= 1) ? 100 : 25), - true); + hiliteCell(rogue.cursorLoc.x, rogue.cursorLoc.y, &white, (steps <= 0 || posEq(path[steps - 1], rogue.cursorLoc) || (!playingBack && distanceBetween(player.loc, rogue.cursorLoc) <= 1) ? 100 : 25), true); oldTargetLoc = rogue.cursorLoc; @@ -701,9 +683,9 @@ void mainInputLoop() { doEvent = moveCursor(&targetConfirmed, &canceled, &tabKey, &rogue.cursorLoc, &theEvent, &state, !textDisplayed, rogue.cursorMode, true); rogue.playbackMode = false; - if (state.buttonChosen == 3) { // Actions menu button. + if (state.buttonChosen == 3) { // Actions menu button. buttonInput = actionMenu(buttons[3].x - 4, playingBack); // Returns the corresponding keystroke. - if (buttonInput == -1) { // Canceled. + if (buttonInput == -1) { // Canceled. doEvent = false; } else { theEvent.eventType = KEYSTROKE; @@ -725,8 +707,7 @@ void mainInputLoop() { rogue.cursorPathIntensity = (rogue.cursorMode ? 50 : 20); } - if (theEvent.eventType == KEYSTROKE - && theEvent.param1 == ACKNOWLEDGE_KEY) { // To unpause by button during playback. + if (theEvent.eventType == KEYSTROKE && theEvent.param1 == ACKNOWLEDGE_KEY) { // To unpause by button during playback. canceled = true; } else { canceled = false; @@ -756,13 +737,13 @@ void mainInputLoop() { && (theEvent.param1 == ASCEND_KEY && rogue.cursorLoc.x == rogue.upLoc.x && rogue.cursorLoc.y == rogue.upLoc.y || theEvent.param1 == DESCEND_KEY && rogue.cursorLoc.x == rogue.downLoc.x && rogue.cursorLoc.y == rogue.downLoc.y)) { - targetConfirmed = true; - doEvent = false; - } + targetConfirmed = true; + doEvent = false; + } } while (!targetConfirmed && !canceled && !doEvent && !rogue.gameHasEnded); if (isPosInMap(oldTargetLoc)) { - refreshDungeonCell(oldTargetLoc.x, oldTargetLoc.y); // Remove old rogue.cursorLoc. + refreshDungeonCell(oldTargetLoc.x, oldTargetLoc.y); // Remove old rogue.cursorLoc. } restoreRNG; @@ -771,13 +752,10 @@ void mainInputLoop() { hideCursor(); confirmMessages(); } else if (targetConfirmed && !playingBack && isPosInMap(rogue.cursorLoc)) { - if (theEvent.eventType == MOUSE_UP - && theEvent.controlKey - && steps > 1) { + if (theEvent.eventType == MOUSE_UP && theEvent.controlKey && steps > 1) { // Control-clicking moves the player one step along the path. - for (dir=0; - dir < DIRECTION_COUNT && !posEq(posNeighborInDirection(player.loc, dir) , path[0]); - dir++); + for (dir = 0; dir < DIRECTION_COUNT && !posEq(posNeighborInDirection(player.loc, dir), path[0]); dir++) + ; playerMoves(dir); } else if (D_WORMHOLING) { travel(rogue.cursorLoc.x, rogue.cursorLoc.y, true); @@ -786,18 +764,18 @@ void mainInputLoop() { if (posEq(originLoc, rogue.cursorLoc)) { confirmMessages(); } else if (abs(player.loc.x - rogue.cursorLoc.x) + abs(player.loc.y - rogue.cursorLoc.y) == 1 // horizontal or vertical - || (distanceBetween(player.loc, rogue.cursorLoc) == 1 // includes diagonals - && (!diagonalBlocked(player.loc.x, player.loc.y, rogue.cursorLoc.x, rogue.cursorLoc.y, !rogue.playbackOmniscience) - || ((pmapAt(rogue.cursorLoc)->flags & HAS_MONSTER) && (monsterAtLoc(rogue.cursorLoc)->info.flags & MONST_ATTACKABLE_THRU_WALLS)) // there's a turret there + || (distanceBetween(player.loc, rogue.cursorLoc) == 1 // includes diagonals + && (!diagonalBlocked(player.loc.x, player.loc.y, rogue.cursorLoc.x, rogue.cursorLoc.y, + !rogue.playbackOmniscience) + || ((pmapAt(rogue.cursorLoc)->flags & HAS_MONSTER) && (monsterAtLoc(rogue.cursorLoc)->info.flags & MONST_ATTACKABLE_THRU_WALLS)) // there's a turret there || ((terrainFlags(rogue.cursorLoc.x, rogue.cursorLoc.y) & T_OBSTRUCTS_PASSABILITY) && (terrainMechFlags(rogue.cursorLoc.x, rogue.cursorLoc.y) & TM_PROMOTES_ON_PLAYER_ENTRY))))) { // there's a lever there - // Clicking one space away will cause the player to try to move there directly irrespective of path. - for (dir=0; - dir < DIRECTION_COUNT && (player.loc.x + nbDirs[dir][0] != rogue.cursorLoc.x || player.loc.y + nbDirs[dir][1] != rogue.cursorLoc.y); - dir++); - playerMoves(dir); - } else if (steps) { - travelRoute(path, steps); - } + // Clicking one space away will cause the player to try to move there directly irrespective of path. + for (dir = 0; dir < DIRECTION_COUNT && (player.loc.x + nbDirs[dir][0] != rogue.cursorLoc.x || player.loc.y + nbDirs[dir][1] != rogue.cursorLoc.y); dir++) + ; + playerMoves(dir); + } else if (steps) { + travelRoute(path, steps); + } } } else if (doEvent) { // If the player entered input during moveCursor() that wasn't a cursor movement command. @@ -836,9 +814,9 @@ void mainInputLoop() { } // accuracy depends on how many clock cycles occur per second -#define MILLISECONDS (clock() * 1000 / CLOCKS_PER_SEC) +#define MILLISECONDS (clock() * 1000 / CLOCKS_PER_SEC) -#define MILLISECONDS_FOR_CAUTION 100 +#define MILLISECONDS_FOR_CAUTION 100 void considerCautiousMode() { /* @@ -862,27 +840,15 @@ void commitDraws() { for (int i = 0; i < COLS; i++) { cellDisplayBuffer *lastPlotted = &previouslyPlottedCells[i][j]; cellDisplayBuffer *curr = &displayBuffer[i][j]; - boolean needsUpdate = - lastPlotted->character != curr->character - || lastPlotted->foreColorComponents[0] != curr->foreColorComponents[0] - || lastPlotted->foreColorComponents[1] != curr->foreColorComponents[1] - || lastPlotted->foreColorComponents[2] != curr->foreColorComponents[2] - || lastPlotted->backColorComponents[0] != curr->backColorComponents[0] - || lastPlotted->backColorComponents[1] != curr->backColorComponents[1] - || lastPlotted->backColorComponents[2] != curr->backColorComponents[2]; + boolean needsUpdate = lastPlotted->character != curr->character || lastPlotted->foreColorComponents[0] != curr->foreColorComponents[0] || lastPlotted->foreColorComponents[1] != curr->foreColorComponents[1] + || lastPlotted->foreColorComponents[2] != curr->foreColorComponents[2] || lastPlotted->backColorComponents[0] != curr->backColorComponents[0] + || lastPlotted->backColorComponents[1] != curr->backColorComponents[1] || lastPlotted->backColorComponents[2] != curr->backColorComponents[2]; if (!needsUpdate) { continue; } - plotChar(curr->character, i, j, - curr->foreColorComponents[0], - curr->foreColorComponents[1], - curr->foreColorComponents[2], - curr->backColorComponents[0], - curr->backColorComponents[1], - curr->backColorComponents[2] - ); + plotChar(curr->character, i, j, curr->foreColorComponents[0], curr->foreColorComponents[1], curr->foreColorComponents[2], curr->backColorComponents[0], curr->backColorComponents[1], curr->backColorComponents[2]); *lastPlotted = *curr; } } @@ -894,14 +860,7 @@ void refreshScreen() { for (int i = 0; i < COLS; i++) { for (int j = 0; j < ROWS; j++) { cellDisplayBuffer *curr = &displayBuffer[i][j]; - plotChar(curr->character, i, j, - curr->foreColorComponents[0], - curr->foreColorComponents[1], - curr->foreColorComponents[2], - curr->backColorComponents[0], - curr->backColorComponents[1], - curr->backColorComponents[2] - ); + plotChar(curr->character, i, j, curr->foreColorComponents[0], curr->foreColorComponents[1], curr->foreColorComponents[2], curr->backColorComponents[0], curr->backColorComponents[1], curr->backColorComponents[2]); // Remember that it was previously plotted, so that // commitDraws still knows when it needs updates. previouslyPlottedCells[i][j] = *curr; @@ -913,8 +872,8 @@ void refreshScreen() { void displayLevel() { short i, j; - for( i=0; i= 0; j--) { + for (i = 0; i < DCOLS; i++) { + for (j = DROWS - 1; j >= 0; j--) { refreshDungeonCell(i, j); } } @@ -972,24 +931,20 @@ void shuffleTerrainColors(short percentOfCells, boolean refreshCells) { assureCosmeticRNG; - for (i=0; i= 100 || rand_range(1, 100) <= percentOfCells)) { - - for (dir=0; dir= 100 || rand_range(1, 100) <= percentOfCells)) { - if (refreshCells) { - refreshDungeonCell(i, j); - } + for (dir = 0; dir < DIRECTION_COUNT; dir++) { + terrainRandomValues[i][j][dir] += rand_range(-600, 600); + terrainRandomValues[i][j][dir] = clamp(terrainRandomValues[i][j][dir], 0, 1000); + } + + if (refreshCells) { + refreshDungeonCell(i, j); } + } } } restoreRNG; @@ -1005,12 +960,12 @@ boolean separateColors(color *fore, const color *back) { f = *fore; b = *back; - f.red = clamp(f.red, 0, 100); - f.green = clamp(f.green, 0, 100); - f.blue = clamp(f.blue, 0, 100); - b.red = clamp(b.red, 0, 100); - b.green = clamp(b.green, 0, 100); - b.blue = clamp(b.blue, 0, 100); + f.red = clamp(f.red, 0, 100); + f.green = clamp(f.green, 0, 100); + f.blue = clamp(f.blue, 0, 100); + b.red = clamp(b.red, 0, 100); + b.green = clamp(b.green, 0, 100); + b.blue = clamp(b.blue, 0, 100); if (f.red + f.blue + f.green > 50 * 3) { modifier = &black; @@ -1021,7 +976,7 @@ boolean separateColors(color *fore, const color *back) { madeChange = false; failsafe = 10; - while(COLOR_DIFF(f, b) < MIN_COLOR_DIFF && --failsafe) { + while (COLOR_DIFF(f, b) < MIN_COLOR_DIFF && --failsafe) { applyColorAverage(&f, modifier, 20); madeChange = true; } @@ -1039,12 +994,12 @@ void normColor(color *baseColor, const short aggregateMultiplier, const short co baseColor->red += colorTranslation; baseColor->green += colorTranslation; baseColor->blue += colorTranslation; - const short vectorLength = baseColor->red + baseColor->green + baseColor->blue; + const short vectorLength = baseColor->red + baseColor->green + baseColor->blue; if (vectorLength != 0) { - baseColor->red = baseColor->red * 300 / vectorLength * aggregateMultiplier / 100; - baseColor->green = baseColor->green * 300 / vectorLength * aggregateMultiplier / 100; - baseColor->blue = baseColor->blue * 300 / vectorLength * aggregateMultiplier / 100; + baseColor->red = baseColor->red * 300 / vectorLength * aggregateMultiplier / 100; + baseColor->green = baseColor->green * 300 / vectorLength * aggregateMultiplier / 100; + baseColor->blue = baseColor->blue * 300 / vectorLength * aggregateMultiplier / 100; } baseColor->redRand = 0; baseColor->greenRand = 0; @@ -1083,7 +1038,7 @@ static enum monsterTypes randomAnimateMonster() { static enum monsterTypes animate[NUMBER_MONSTER_KINDS]; if (listLength == 0) { - for (int i=0; i < NUMBER_MONSTER_KINDS; i++) { + for (int i = 0; i < NUMBER_MONSTER_KINDS; i++) { if (!(monsterCatalog[i].flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { animate[listLength++] = i; } @@ -1104,8 +1059,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r creature *monst = NULL; item *theItem = NULL; enum tileType tile = NOTHING; - const enum displayGlyph itemChars[] = {G_POTION, G_SCROLL, G_FOOD, G_WAND, - G_STAFF, G_GOLD, G_ARMOR, G_WEAPON, G_RING, G_CHARM}; + const enum displayGlyph itemChars[] = {G_POTION, G_SCROLL, G_FOOD, G_WAND, G_STAFF, G_GOLD, G_ARMOR, G_WEAPON, G_RING, G_CHARM}; enum dungeonLayers layer, maxLayer; assureCosmeticRNG; @@ -1113,13 +1067,12 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r brogueAssert(coordinatesAreInMap(x, y)); if (pmap[x][y].flags & HAS_MONSTER) { - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); } else if (pmap[x][y].flags & HAS_DORMANT_MONSTER) { - monst = dormantMonsterAtLoc((pos){ x, y }); + monst = dormantMonsterAtLoc((pos){x, y}); } if (monst) { - monsterWithDetectedItem = (monst->carriedItem && (monst->carriedItem->flags & ITEM_MAGIC_DETECTED) - && itemMagicPolarity(monst->carriedItem) && !canSeeMonster(monst)); + monsterWithDetectedItem = (monst->carriedItem && (monst->carriedItem->flags & ITEM_MAGIC_DETECTED) && itemMagicPolarity(monst->carriedItem) && !canSeeMonster(monst)); } if (monsterWithDetectedItem) { @@ -1128,11 +1081,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r theItem = itemAtLoc(x, y); } - if (!playerCanSeeOrSense(x, y) - && !(pmap[x][y].flags & (ITEM_DETECTED | HAS_PLAYER)) - && (!monst || !monsterRevealed(monst)) - && !monsterWithDetectedItem - && (pmap[x][y].flags & (DISCOVERED | MAGIC_MAPPED)) + if (!playerCanSeeOrSense(x, y) && !(pmap[x][y].flags & (ITEM_DETECTED | HAS_PLAYER)) && (!monst || !monsterRevealed(monst)) && !monsterWithDetectedItem && (pmap[x][y].flags & (DISCOVERED | MAGIC_MAPPED)) && (pmap[x][y].flags & STABLE_MEMORY)) { // restore memory @@ -1166,20 +1115,17 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r tile = dungeonFeatureCatalog[tileCatalog[tile].discoverType].tile; } - if (tileCatalog[tile].drawPriority < bestFCPriority - && tileCatalog[tile].foreColor) { + if (tileCatalog[tile].drawPriority < bestFCPriority && tileCatalog[tile].foreColor) { cellForeColor = *(tileCatalog[tile].foreColor); bestFCPriority = tileCatalog[tile].drawPriority; } - if (tileCatalog[tile].drawPriority < bestBCPriority - && tileCatalog[tile].backColor) { + if (tileCatalog[tile].drawPriority < bestBCPriority && tileCatalog[tile].backColor) { cellBackColor = *(tileCatalog[tile].backColor); bestBCPriority = tileCatalog[tile].drawPriority; } - if (tileCatalog[tile].drawPriority < bestCharPriority - && tileCatalog[tile].displayChar) { + if (tileCatalog[tile].drawPriority < bestCharPriority && tileCatalog[tile].displayChar) { cellChar = tileCatalog[tile].displayChar; bestCharPriority = tileCatalog[tile].drawPriority; @@ -1194,8 +1140,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r colorMultiplierFromDungeonLight(x, y, &lightMultiplierColor); } - if (pmap[x][y].layers[GAS] - && tileCatalog[pmap[x][y].layers[GAS]].backColor) { + if (pmap[x][y].layers[GAS] && tileCatalog[pmap[x][y].layers[GAS]].backColor) { gasAugmentColor = *(tileCatalog[pmap[x][y].layers[GAS]].backColor); if (rogue.trueColorMode) { @@ -1217,10 +1162,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r cellChar = player.info.displayChar; cellForeColor = *(player.info.foreColor); needDistinctness = true; - } else if (((pmap[x][y].flags & HAS_ITEM) && (pmap[x][y].flags & ITEM_DETECTED) - && itemMagicPolarity(theItem) - && !playerCanSeeOrSense(x, y)) - || monsterWithDetectedItem){ + } else if (((pmap[x][y].flags & HAS_ITEM) && (pmap[x][y].flags & ITEM_DETECTED) && itemMagicPolarity(theItem) && !playerCanSeeOrSense(x, y)) || monsterWithDetectedItem) { int polarity = itemMagicPolarity(theItem); if (theItem->category == AMULET) { @@ -1238,14 +1180,9 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r } needDistinctness = true; - } else if ((pmap[x][y].flags & HAS_MONSTER) - && (playerCanSeeOrSense(x, y) || ((monst->info.flags & MONST_IMMOBILE) && (pmap[x][y].flags & DISCOVERED))) - && (!monsterIsHidden(monst, &player) || rogue.playbackOmniscience)) { + } else if ((pmap[x][y].flags & HAS_MONSTER) && (playerCanSeeOrSense(x, y) || ((monst->info.flags & MONST_IMMOBILE) && (pmap[x][y].flags & DISCOVERED))) && (!monsterIsHidden(monst, &player) || rogue.playbackOmniscience)) { needDistinctness = true; - if (player.status[STATUS_HALLUCINATING] > 0 - && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) - && !rogue.playbackOmniscience - && !player.status[STATUS_TELEPATHIC]) { + if (player.status[STATUS_HALLUCINATING] > 0 && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) && !rogue.playbackOmniscience && !player.status[STATUS_TELEPATHIC]) { cellChar = monsterCatalog[randomAnimateMonster()].displayChar; cellForeColor = *(monsterCatalog[randomAnimateMonster()].foreColor); } else { @@ -1253,7 +1190,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r cellForeColor = *(monst->info.foreColor); if (monst->status[STATUS_INVISIBLE] || (monst->bookkeepingFlags & MB_SUBMERGED)) { // Invisible allies show up on the screen with a transparency effect. - //cellForeColor = cellBackColor; + // cellForeColor = cellBackColor; applyColorAverage(&cellForeColor, &cellBackColor, 75); } else { if (monst->creatureState == MONSTER_ALLY && !(monst->info.flags & MONST_INANIMATE)) { @@ -1264,11 +1201,9 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r } } } - //DEBUG if (monst->bookkeepingFlags & MB_LEADER) applyColorAverage(&cellBackColor, &purple, 50); + // DEBUG if (monst->bookkeepingFlags & MB_LEADER) applyColorAverage(&cellBackColor, &purple, 50); } - } else if (monst - && monsterRevealed(monst) - && !canSeeMonster(monst)) { + } else if (monst && monsterRevealed(monst) && !canSeeMonster(monst)) { if (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience && !player.status[STATUS_TELEPATHIC]) { cellChar = (rand_range(0, 1) ? 'X' : 'x'); } else { @@ -1280,8 +1215,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r cellBackColor = black; gasAugmentColor = black; } - } else if ((pmap[x][y].flags & HAS_ITEM) && !cellHasTerrainFlag(x, y, T_OBSTRUCTS_ITEMS) - && (playerCanSeeOrSense(x, y) || ((pmap[x][y].flags & DISCOVERED) && !cellHasTerrainFlag(x, y, T_MOVES_ITEMS)))) { + } else if ((pmap[x][y].flags & HAS_ITEM) && !cellHasTerrainFlag(x, y, T_OBSTRUCTS_ITEMS) && (playerCanSeeOrSense(x, y) || ((pmap[x][y].flags & DISCOVERED) && !cellHasTerrainFlag(x, y, T_MOVES_ITEMS)))) { needDistinctness = true; if (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience) { cellChar = itemChars[rand_range(0, 9)]; @@ -1319,11 +1253,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r applyColorAverage(&cellForeColor, &gasAugmentColor, gasAugmentWeight); } // phantoms create sillhouettes in gas clouds - if ((pmap[x][y].flags & HAS_MONSTER) - && monst->status[STATUS_INVISIBLE] - && playerCanSeeOrSense(x, y) - && !monsterRevealed(monst) - && !monsterHiddenBySubmersion(monst, &player)) { + if ((pmap[x][y].flags & HAS_MONSTER) && monst->status[STATUS_INVISIBLE] && playerCanSeeOrSense(x, y) && !monsterRevealed(monst) && !monsterHiddenBySubmersion(monst, &player)) { if (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience && !player.status[STATUS_TELEPATHIC]) { cellChar = monsterCatalog[randomAnimateMonster()].displayChar; @@ -1335,9 +1265,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r applyColorAverage(&cellBackColor, &gasAugmentColor, gasAugmentWeight); } - if (!(pmap[x][y].flags & (ANY_KIND_OF_VISIBLE | ITEM_DETECTED | HAS_PLAYER)) - && !playerCanSeeOrSense(x, y) - && (!monst || !monsterRevealed(monst)) && !monsterWithDetectedItem) { + if (!(pmap[x][y].flags & (ANY_KIND_OF_VISIBLE | ITEM_DETECTED | HAS_PLAYER)) && !playerCanSeeOrSense(x, y) && (!monst || !monsterRevealed(monst)) && !monsterWithDetectedItem) { pmap[x][y].flags |= STABLE_MEMORY; pmap[x][y].rememberedAppearance.character = cellChar; @@ -1364,14 +1292,11 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r } // Smooth out walls: if there's a "wall-ish" tile drawn below us, just draw the wall top - if ((cellChar == G_WALL || cellChar == G_GRANITE) && coordinatesAreInMap(x, y+1) - && glyphIsWallish(displayBuffer[mapToWindowX(x)][mapToWindowY(y+1)].character)) { + if ((cellChar == G_WALL || cellChar == G_GRANITE) && coordinatesAreInMap(x, y + 1) && glyphIsWallish(displayBuffer[mapToWindowX(x)][mapToWindowY(y + 1)].character)) { cellChar = G_WALL_TOP; } - if (((pmap[x][y].flags & ITEM_DETECTED) || monsterWithDetectedItem - || (monst && monsterRevealed(monst))) - && !playerCanSeeOrSense(x, y)) { + if (((pmap[x][y].flags & ITEM_DETECTED) || monsterWithDetectedItem || (monst && monsterRevealed(monst))) && !playerCanSeeOrSense(x, y)) { // do nothing } else if (!(pmap[x][y].flags & VISIBLE) && (pmap[x][y].flags & CLAIRVOYANT_VISIBLE)) { // can clairvoyantly see it @@ -1414,8 +1339,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r applyColorAverage(&cellForeColor, &black, 80); applyColorAverage(&cellBackColor, &black, 80); } else { - if (!cellHasTMFlag(x, y, TM_BRIGHT_MEMORY) - && (!rogue.trueColorMode || !needDistinctness)) { + if (!cellHasTMFlag(x, y, TM_BRIGHT_MEMORY) && (!rogue.trueColorMode || !needDistinctness)) { applyColorMultiplier(&cellForeColor, &memoryColor); applyColorAverage(&cellForeColor, &memoryOverlay, 25); @@ -1447,9 +1371,9 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r applyColorMultiplier(&cellBackColor, &deepWaterLightColor); } } -// DEBUG cellBackColor.red = max(0,((scentMap[x][y] - rogue.scentTurnNumber) * 2) + 100); -// DEBUG if (pmap[x][y].flags & KNOWN_TO_BE_TRAP_FREE) cellBackColor.red += 20; -// DEBUG if (cellHasTerrainFlag(x, y, T_IS_FLAMMABLE)) cellBackColor.red += 50; + // DEBUG cellBackColor.red = max(0,((scentMap[x][y] - rogue.scentTurnNumber) * 2) + 100); + // DEBUG if (pmap[x][y].flags & KNOWN_TO_BE_TRAP_FREE) cellBackColor.red += 20; + // DEBUG if (cellHasTerrainFlag(x, y, T_IS_FLAMMABLE)) cellBackColor.red += 50; if (pmap[x][y].flags & IS_IN_PATH) { if (cellHasTMFlag(x, y, TM_INVERT_WHEN_HIGHLIGHTED)) { @@ -1475,8 +1399,7 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r } } - if ((rogue.trueColorMode || rogue.displayStealthRangeMode) - && playerCanSeeOrSense(x, y)) { + if ((rogue.trueColorMode || rogue.displayStealthRangeMode) && playerCanSeeOrSense(x, y)) { if (displayDetail[x][y] == DV_DARK) { applyColorMultiplier(&cellForeColor, &inDarknessMultiplierColor); @@ -1489,8 +1412,8 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r colorMultiplierFromDungeonLight(x, y, &lightMultiplierColor); normColor(&lightMultiplierColor, 175, 50); - //applyColorMultiplier(&cellForeColor, &lightMultiplierColor); - //applyColorMultiplier(&cellBackColor, &lightMultiplierColor); + // applyColorMultiplier(&cellForeColor, &lightMultiplierColor); + // applyColorMultiplier(&cellBackColor, &lightMultiplierColor); applyColorAugment(&cellForeColor, &lightMultiplierColor, 5); applyColorAugment(&cellBackColor, &lightMultiplierColor, 5); } @@ -1501,11 +1424,11 @@ void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *r } if (D_SCENT_VISION) { - if (rogue.scentTurnNumber > (unsigned short) scentMap[x][y]) { - cellBackColor.red = rogue.scentTurnNumber - (unsigned short) scentMap[x][y]; + if (rogue.scentTurnNumber > (unsigned short)scentMap[x][y]) { + cellBackColor.red = rogue.scentTurnNumber - (unsigned short)scentMap[x][y]; cellBackColor.red = clamp(cellBackColor.red, 0, 100); } else { - cellBackColor.green = abs(rogue.scentTurnNumber - (unsigned short) scentMap[x][y]); + cellBackColor.green = abs(rogue.scentTurnNumber - (unsigned short)scentMap[x][y]); cellBackColor.green = clamp(cellBackColor.green, 0, 100); } } @@ -1524,7 +1447,7 @@ void refreshDungeonCell(short x, short y) { brogueAssert(coordinatesAreInMap(x, y)); getCellAppearance(x, y, &cellChar, &foreColor, &backColor); - plotCharWithColor(cellChar, mapToWindow((pos){ x, y }), &foreColor, &backColor); + plotCharWithColor(cellChar, mapToWindow((pos){x, y}), &foreColor, &backColor); } void applyColorMultiplier(color *baseColor, const color *multiplierColor) { @@ -1535,7 +1458,7 @@ void applyColorMultiplier(color *baseColor, const color *multiplierColor) { baseColor->blue = baseColor->blue * multiplierColor->blue / 100; baseColor->blueRand = baseColor->blueRand * multiplierColor->blueRand / 100; baseColor->rand = baseColor->rand * multiplierColor->rand / 100; - //baseColor->colorDances *= multiplierColor->colorDances; + // baseColor->colorDances *= multiplierColor->colorDances; return; } @@ -1564,23 +1487,23 @@ void applyColorAugment(color *baseColor, const color *augmentingColor, short aug } void applyColorScalar(color *baseColor, short scalar) { - baseColor->red = baseColor->red * scalar / 100; - baseColor->redRand = baseColor->redRand * scalar / 100; - baseColor->green = baseColor->green * scalar / 100; - baseColor->greenRand = baseColor->greenRand * scalar / 100; - baseColor->blue = baseColor->blue * scalar / 100; - baseColor->blueRand = baseColor->blueRand * scalar / 100; - baseColor->rand = baseColor->rand * scalar / 100; + baseColor->red = baseColor->red * scalar / 100; + baseColor->redRand = baseColor->redRand * scalar / 100; + baseColor->green = baseColor->green * scalar / 100; + baseColor->greenRand = baseColor->greenRand * scalar / 100; + baseColor->blue = baseColor->blue * scalar / 100; + baseColor->blueRand = baseColor->blueRand * scalar / 100; + baseColor->rand = baseColor->rand * scalar / 100; } void applyColorBounds(color *baseColor, short lowerBound, short upperBound) { - baseColor->red = clamp(baseColor->red, lowerBound, upperBound); - baseColor->redRand = clamp(baseColor->redRand, lowerBound, upperBound); - baseColor->green = clamp(baseColor->green, lowerBound, upperBound); - baseColor->greenRand = clamp(baseColor->greenRand, lowerBound, upperBound); - baseColor->blue = clamp(baseColor->blue, lowerBound, upperBound); - baseColor->blueRand = clamp(baseColor->blueRand, lowerBound, upperBound); - baseColor->rand = clamp(baseColor->rand, lowerBound, upperBound); + baseColor->red = clamp(baseColor->red, lowerBound, upperBound); + baseColor->redRand = clamp(baseColor->redRand, lowerBound, upperBound); + baseColor->green = clamp(baseColor->green, lowerBound, upperBound); + baseColor->greenRand = clamp(baseColor->greenRand, lowerBound, upperBound); + baseColor->blue = clamp(baseColor->blue, lowerBound, upperBound); + baseColor->blueRand = clamp(baseColor->blueRand, lowerBound, upperBound); + baseColor->rand = clamp(baseColor->rand, lowerBound, upperBound); } void desaturate(color *baseColor, short weight) { @@ -1598,9 +1521,7 @@ void desaturate(color *baseColor, short weight) { baseColor->rand += avg * weight / 3 / 100; } -short randomizeByPercent(short input, short percent) { - return (rand_range(input * (100 - percent) / 100, input * (100 + percent) / 100)); -} +short randomizeByPercent(short input, short percent) { return (rand_range(input * (100 - percent) / 100, input * (100 + percent) / 100)); } void randomizeColor(color *baseColor, short randomizePercent) { baseColor->red = randomizeByPercent(baseColor->red, randomizePercent); @@ -1615,10 +1536,8 @@ void swapColors(color *color1, color *color2) { } // Assumes colors are pre-baked. -void blendAppearances(const color *fromForeColor, const color *fromBackColor, const enum displayGlyph fromChar, - const color *toForeColor, const color *toBackColor, const enum displayGlyph toChar, - color *retForeColor, color *retBackColor, enum displayGlyph *retChar, - const short percent) { +void blendAppearances(const color *fromForeColor, const color *fromBackColor, const enum displayGlyph fromChar, const color *toForeColor, const color *toBackColor, const enum displayGlyph toChar, color *retForeColor, color *retBackColor, + enum displayGlyph *retChar, const short percent) { // Straight average of the back color: *retBackColor = *fromBackColor; applyColorAverage(retBackColor, toBackColor, percent); @@ -1636,7 +1555,8 @@ void blendAppearances(const color *fromForeColor, const color *fromBackColor, co *retForeColor = *fromForeColor; applyColorAverage(retForeColor, toForeColor, percent); } else { - // If it is changing, the first half blends to the current back color, and the second half blends to the final back color. + // If it is changing, the first half blends to the current back color, and the second half blends to the final + // back color. if (percent >= 50) { *retForeColor = *retBackColor; applyColorAverage(retForeColor, toForeColor, (percent - 50) * 2); @@ -1647,11 +1567,7 @@ void blendAppearances(const color *fromForeColor, const color *fromBackColor, co } } -void irisFadeBetweenBuffers(cellDisplayBuffer fromBuf[COLS][ROWS], - cellDisplayBuffer toBuf[COLS][ROWS], - short x, short y, - short frameCount, - boolean outsideIn) { +void irisFadeBetweenBuffers(cellDisplayBuffer fromBuf[COLS][ROWS], cellDisplayBuffer toBuf[COLS][ROWS], short x, short y, short frameCount, boolean outsideIn) { short i, j, frame, percentBasis, thisCellPercent; boolean fastForward; color fromBackColor, toBackColor, fromForeColor, toForeColor, currentForeColor, currentBackColor; @@ -1672,12 +1588,12 @@ void irisFadeBetweenBuffers(cellDisplayBuffer fromBuf[COLS][ROWS], } else { j = y; } - maxDistance = i*i + j*j; + maxDistance = i * i + j * j; // Generate the initial completion map as a percent of maximum distance. - for (i=0; ired = editColor->redRand = adjustedLightValue(max(0, tmap[x][y].light[0])); - editColor->green = editColor->greenRand = adjustedLightValue(max(0, tmap[x][y].light[1])); - editColor->blue = editColor->blueRand = adjustedLightValue(max(0, tmap[x][y].light[2])); + editColor->red = editColor->redRand = adjustedLightValue(max(0, tmap[x][y].light[0])); + editColor->green = editColor->greenRand = adjustedLightValue(max(0, tmap[x][y].light[1])); + editColor->blue = editColor->blueRand = adjustedLightValue(max(0, tmap[x][y].light[2])); editColor->rand = adjustedLightValue(max(0, tmap[x][y].light[0] + tmap[x][y].light[1] + tmap[x][y].light[2]) / 3); editColor->colorDances = false; @@ -1763,15 +1679,11 @@ void colorMultiplierFromDungeonLight(short x, short y, color *editColor) { void plotCharWithColor(enum displayGlyph inputChar, windowpos loc, const color *cellForeColor, const color *cellBackColor) { short oldRNG; - short foreRed = cellForeColor->red, - foreGreen = cellForeColor->green, - foreBlue = cellForeColor->blue, + short foreRed = cellForeColor->red, foreGreen = cellForeColor->green, foreBlue = cellForeColor->blue, - backRed = cellBackColor->red, - backGreen = cellBackColor->green, - backBlue = cellBackColor->blue, + backRed = cellBackColor->red, backGreen = cellBackColor->green, backBlue = cellBackColor->blue, - foreRand, backRand; + foreRand, backRand; brogueAssert(locIsInWindow(loc)); @@ -1779,7 +1691,7 @@ void plotCharWithColor(enum displayGlyph inputChar, windowpos loc, const color * return; } - //assureCosmeticRNG; + // assureCosmeticRNG; oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; @@ -1792,17 +1704,14 @@ void plotCharWithColor(enum displayGlyph inputChar, windowpos loc, const color * backGreen += rand_range(0, cellBackColor->greenRand) + backRand; backBlue += rand_range(0, cellBackColor->blueRand) + backRand; - foreRed = min(100, max(0, foreRed)); - foreGreen = min(100, max(0, foreGreen)); - foreBlue = min(100, max(0, foreBlue)); - backRed = min(100, max(0, backRed)); - backGreen = min(100, max(0, backGreen)); - backBlue = min(100, max(0, backBlue)); + foreRed = min(100, max(0, foreRed)); + foreGreen = min(100, max(0, foreGreen)); + foreBlue = min(100, max(0, foreBlue)); + backRed = min(100, max(0, backRed)); + backGreen = min(100, max(0, backGreen)); + backBlue = min(100, max(0, backBlue)); - if (inputChar != ' ' - && foreRed == backRed - && foreGreen == backGreen - && foreBlue == backBlue) { + if (inputChar != ' ' && foreRed == backRed && foreGreen == backGreen && foreBlue == backBlue) { inputChar = ' '; } @@ -1831,9 +1740,9 @@ void plotCharToBuffer(enum displayGlyph inputChar, windowpos loc, const color *f oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; - cellDisplayBuffer* cell = &dbuf[loc.window_x][loc.window_y]; + cellDisplayBuffer *cell = &dbuf[loc.window_x][loc.window_y]; cell->foreColorComponents[0] = foreColor->red + rand_range(0, foreColor->redRand) + rand_range(0, foreColor->rand); cell->foreColorComponents[1] = foreColor->green + rand_range(0, foreColor->greenRand) + rand_range(0, foreColor->rand); cell->foreColorComponents[2] = foreColor->blue + rand_range(0, foreColor->blueRand) + rand_range(0, foreColor->rand); @@ -1854,7 +1763,7 @@ void plotForegroundChar(enum displayGlyph inputChar, short x, short y, const col colorMultiplierFromDungeonLight(x, y, &multColor); applyColorMultiplier(&myColor, &multColor); } - plotCharWithColor(inputChar, mapToWindow((pos){ x, y }), &myColor, &backColor); + plotCharWithColor(inputChar, mapToWindow((pos){x, y}), &myColor, &backColor); } // Debug feature: display the level to the screen without regard to lighting, field of view, etc. @@ -1863,10 +1772,9 @@ void dumpLevelToScreen() { pcell backup; assureCosmeticRNG; - for (i=0; i= 0; j--) { - for (i=0; i= 0; j--) { + for (i = 0; i < count; i++) { percent = flashStrength[i] * j / frames; newColor = fColor[i]; applyColorAverage(&newColor, flashColor[i], percent); - plotCharWithColor(displayChar[i], mapToWindow((pos){ x[i], y[i] }), &newColor, &(bColor[i])); + plotCharWithColor(displayChar[i], mapToWindow((pos){x[i], y[i]}), &newColor, &(bColor[i])); } if (j) { if (pauseAnimation(16)) { @@ -2063,7 +1971,7 @@ void flashCell(const color *theColor, short frames, short x, short y) { short i; boolean interrupted = false; - for (i=0; i= 0 : n <= stepCount); n += (invert ? -1 : 1)) { - for (i=0; i= 0 : n <= stepCount); n += (invert ? -1 : 1)) { + for (i = 0; i < COLS; i++) { + for (j = 0; j < ROWS; j++) { - percentComplete = (double) (n) * 100 / stepCount; + percentComplete = (double)(n)*100 / stepCount; colorMid = *colorStart; if (colorEnd) { @@ -2163,8 +2067,7 @@ void funkyFade(cellDisplayBuffer displayBuf[COLS][ROWS], const color *colorStart } // the fade color floods the reachable dungeon tiles faster - if (!invert && coordinatesAreInMap(windowToMapX(i), windowToMapY(j)) - && distanceMap[windowToMapX(i)][windowToMapY(j)] >= 0 && distanceMap[windowToMapX(i)][windowToMapY(j)] < 30000) { + if (!invert && coordinatesAreInMap(windowToMapX(i), windowToMapY(j)) && distanceMap[windowToMapX(i)][windowToMapY(j)] >= 0 && distanceMap[windowToMapX(i)][windowToMapY(j)] < 30000) { percentComplete *= 1.0 + (100.0 - min(100, distanceMap[windowToMapX(i)][windowToMapY(j)])) / 100.; } @@ -2189,9 +2092,7 @@ void funkyFade(cellDisplayBuffer displayBuf[COLS][ROWS], const color *colorStart foreColor = (invert ? white : black); - if (j == (MESSAGE_LINES - 1) - && i >= mapToWindowX(0) - && i < mapToWindowX(strLenWithoutEscapes(displayedMessage[MESSAGE_LINES - j - 1]))) { + if (j == (MESSAGE_LINES - 1) && i >= mapToWindowX(0) && i < mapToWindowX(strLenWithoutEscapes(displayedMessage[MESSAGE_LINES - j - 1]))) { tempChar = displayedMessage[MESSAGE_LINES - j - 1][windowToMapX(i)]; } else { tempChar = displayBuf[i][j].character; @@ -2203,7 +2104,7 @@ void funkyFade(cellDisplayBuffer displayBuf[COLS][ROWS], const color *colorStart applyColorAverage(&foreColor, &tempColor, weight); } applyColorAverage(&backColor, &tempColor, weight); - plotCharWithColor(tempChar, (windowpos){ i, j }, &foreColor, &backColor); + plotCharWithColor(tempChar, (windowpos){i, j}, &foreColor, &backColor); } } if (!fastForward && pauseAnimation(16)) { @@ -2223,16 +2124,16 @@ void funkyFade(cellDisplayBuffer displayBuf[COLS][ROWS], const color *colorStart void displayWaypoints() { short i, j, w, lowestDistance; - for (i=0; ieventType == MOUSE_UP && !locIsInWindow((windowpos){ returnEvent->param1, returnEvent->param2 })); + nextKeyOrMouseEvent(returnEvent, textInput, + colorsDance); // No mouse clicks outside of the window will register. + } while (returnEvent->eventType == MOUSE_UP && !locIsInWindow((windowpos){returnEvent->param1, returnEvent->param2})); // recording done elsewhere } @@ -2592,11 +2491,9 @@ void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKe displayLevel(); refreshSideBar(-1, -1, false); if (rogue.trueColorMode) { - messageWithColor(KEYBOARD_LABELS ? "Color effects disabled. Press '\\' again to enable." : "Color effects disabled.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Color effects disabled. Press '\\' again to enable." : "Color effects disabled.", &teal, 0); } else { - messageWithColor(KEYBOARD_LABELS ? "Color effects enabled. Press '\\' again to disable." : "Color effects enabled.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Color effects enabled. Press '\\' again to disable." : "Color effects enabled.", &teal, 0); } break; case STEALTH_RANGE_KEY: @@ -2604,11 +2501,9 @@ void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKe displayLevel(); refreshSideBar(-1, -1, false); if (rogue.displayStealthRangeMode) { - messageWithColor(KEYBOARD_LABELS ? "Stealth range displayed. Press ']' again to hide." : "Stealth range displayed.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Stealth range displayed. Press ']' again to hide." : "Stealth range displayed.", &teal, 0); } else { - messageWithColor(KEYBOARD_LABELS ? "Stealth range hidden. Press ']' again to display." : "Stealth range hidden.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Stealth range hidden. Press ']' again to display." : "Stealth range hidden.", &teal, 0); } break; case CALL_KEY: @@ -2633,9 +2528,7 @@ void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKe printDiscoveriesScreen(); break; case CREATE_ITEM_MONSTER_KEY: - DEBUG { - dialogCreateItemOrMonster(); - } + DEBUG { dialogCreateItemOrMonster(); } break; case SAVE_GAME_KEY: if (rogue.playbackMode || serverMode) { @@ -2663,19 +2556,13 @@ void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKe graphicsMode = setGraphicsMode((graphicsMode + 1) % 3); switch (graphicsMode) { case TEXT_GRAPHICS: - messageWithColor(KEYBOARD_LABELS - ? "Switched to text mode. Press 'G' again to enable tiles." - : "Switched to text mode.", &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Switched to text mode. Press 'G' again to enable tiles." : "Switched to text mode.", &teal, 0); break; case TILES_GRAPHICS: - messageWithColor(KEYBOARD_LABELS - ? "Switched to graphical tiles. Press 'G' again to enable hybrid mode." - : "Switched to graphical tiles.", &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Switched to graphical tiles. Press 'G' again to enable hybrid mode." : "Switched to graphical tiles.", &teal, 0); break; case HYBRID_GRAPHICS: - messageWithColor(KEYBOARD_LABELS - ? "Switched to hybrid mode. Press 'G' again to disable tiles." - : "Switched to hybrid mode.", &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Switched to hybrid mode. Press 'G' again to disable tiles." : "Switched to hybrid mode.", &teal, 0); break; } } @@ -2689,15 +2576,16 @@ void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKe // DEBUG displayLoops(); // DEBUG displayChokeMap(); DEBUG displayMachines(); - //DEBUG displayWaypoints(); + // DEBUG displayWaypoints(); // DEBUG {displayGrid(safetyMap); displayMoreSign(); displayLevel();} // parseFile(); - // DEBUG spawnDungeonFeature(player.loc.x, player.loc.y, &dungeonFeatureCatalog[DF_METHANE_GAS_ARMAGEDDON], true, false); + // DEBUG spawnDungeonFeature(player.loc.x, player.loc.y, &dungeonFeatureCatalog[DF_METHANE_GAS_ARMAGEDDON], + // true, false); printSeed(); break; case EASY_MODE_KEY: - //if (shiftKey) { - enableEasyMode(); + // if (shiftKey) { + enableEasyMode(); //} break; case PRINTSCREEN_KEY: @@ -2729,13 +2617,7 @@ void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKe rogue.cautiousMode = false; } -boolean getInputTextString(char *inputText, - const char *prompt, - short maxLength, - const char *defaultEntry, - const char *promptSuffix, - short textEntryType, - boolean useDialogBox) { +boolean getInputTextString(char *inputText, const char *prompt, short maxLength, const char *defaultEntry, const char *promptSuffix, short textEntryType, boolean useDialogBox) { short charNum, i, x, y; char keystroke, suffix[100]; const short textEntryBounds[TEXT_INPUT_TYPES][2] = {{' ', '~'}, {' ', '~'}, {'0', '9'}}; @@ -2746,12 +2628,11 @@ boolean getInputTextString(char *inputText, x = (COLS - max(maxLength, strLenWithoutEscapes(prompt))) / 2; y = ROWS / 2 - 1; clearDisplayBuffer(dbuf); - rectangularShading(x - 1, y - 2, max(maxLength, strLenWithoutEscapes(prompt)) + 2, - 4, &interfaceBoxColor, INTERFACE_OPACITY, dbuf); + rectangularShading(x - 1, y - 2, max(maxLength, strLenWithoutEscapes(prompt)) + 2, 4, &interfaceBoxColor, INTERFACE_OPACITY, dbuf); overlayDisplayBuffer(dbuf, rbuf); printString(prompt, x, y - 1, &white, &interfaceBoxColor, NULL); - for (i=0; i 0) { printString(suffix, charNum + x - 1, y, &gray, &black, 0); - plotCharWithColor(' ', (windowpos){ x + charNum + strlen(suffix) - 1, y }, &black, &black); + plotCharWithColor(' ', (windowpos){x + charNum + strlen(suffix) - 1, y}, &black, &black); charNum--; inputText[charNum] = ' '; - } else if (keystroke >= textEntryBounds[textEntryType][0] - && keystroke <= textEntryBounds[textEntryType][1]) { // allow only permitted input + } else if (keystroke >= textEntryBounds[textEntryType][0] && keystroke <= textEntryBounds[textEntryType][1]) { // allow only permitted input - if (textEntryType == TEXT_INPUT_FILENAME - && characterForbiddenInFilename(keystroke)) { + if (textEntryType == TEXT_INPUT_FILENAME && characterForbiddenInFilename(keystroke)) { keystroke = '-'; } inputText[charNum] = keystroke; - plotCharWithColor(keystroke, (windowpos){ x + charNum, y }, &white, &black); + plotCharWithColor(keystroke, (windowpos){x + charNum, y}, &white, &black); printString(suffix, charNum + x + 1, y, &gray, &black, 0); if (charNum < maxLength) { charNum++; @@ -2806,18 +2684,16 @@ boolean getInputTextString(char *inputText, } #ifdef USE_CLIPBOARD else if (keystroke == TAB_KEY) { - char* clipboard = getClipboard(); - for (int i=0; i<(int) min(strlen(clipboard), (unsigned long) (maxLength - charNum)); ++i) { + char *clipboard = getClipboard(); + for (int i = 0; i < (int)min(strlen(clipboard), (unsigned long)(maxLength - charNum)); ++i) { char character = clipboard[i]; - if (character >= textEntryBounds[textEntryType][0] - && character <= textEntryBounds[textEntryType][1]) { // allow only permitted input - if (textEntryType == TEXT_INPUT_FILENAME - && characterForbiddenInFilename(character)) { + if (character >= textEntryBounds[textEntryType][0] && character <= textEntryBounds[textEntryType][1]) { // allow only permitted input + if (textEntryType == TEXT_INPUT_FILENAME && characterForbiddenInFilename(character)) { character = '-'; } - plotCharWithColor(character, (windowpos){ x + charNum, y }, &white, &black); + plotCharWithColor(character, (windowpos){x + charNum, y}, &white, &black); if (charNum < maxLength) { charNum++; } @@ -2841,14 +2717,12 @@ boolean getInputTextString(char *inputText, return true; } -void displayCenteredAlert(char *message) { - printString(message, (COLS - strLenWithoutEscapes(message)) / 2, ROWS / 2, &teal, &black, 0); -} +void displayCenteredAlert(char *message) { printString(message, (COLS - strLenWithoutEscapes(message)) / 2, ROWS / 2, &teal, &black, 0); } // Flashes a message on the screen starting at (x, y) lasting for the given time (in ms) and with the given colors. void flashMessage(char *message, short x, short y, int time, const color *fColor, const color *bColor) { boolean fastForward; - int i, j, messageLength, percentComplete, previousPercentComplete; + int i, j, messageLength, percentComplete, previousPercentComplete; color backColors[COLS], backColor, foreColor; cellDisplayBuffer dbufs[COLS]; enum displayGlyph dchar; @@ -2861,23 +2735,23 @@ void flashMessage(char *message, short x, short y, int time, const color *fColor oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; messageLength = strLenWithoutEscapes(message); fastForward = false; - for (j=0; jflags & FOLDABLE)) { - formatCountedMessage(buffer, COLS*2, m); + formatCountedMessage(buffer, COLS * 2, m); return folded; } @@ -3082,22 +2947,22 @@ short foldMessages(char buffer[COLS*20], short offset, unsigned long *turnOutput buffer[length] = '\0'; for (i = folded; i >= 1; i--) { m = getArchivedMessage(offset + i); - formatCountedMessage(counted, COLS*2, m); + formatCountedMessage(counted, COLS * 2, m); messageLength = strLenWithoutEscapes(counted); if (length == 0) { - length = snprintf(buffer, COLS*20, "%s", counted); + length = snprintf(buffer, COLS * 20, "%s", counted); lineLength = messageLength; - } else if (lineLength + 3 + messageLength <= DCOLS) { // + 3 for semi-colon, space and final period - length += snprintf(&buffer[length], COLS*20 - length, "; %s", counted); + } else if (lineLength + 3 + messageLength <= DCOLS) { // + 3 for semi-colon, space and final period + length += snprintf(&buffer[length], COLS * 20 - length, "; %s", counted); lineLength += 2 + messageLength; } else { - length += snprintf(&buffer[length], COLS*20 - length, ".\n%s", counted); + length += snprintf(&buffer[length], COLS * 20 - length, ".\n%s", counted); lineLength = messageLength; } } - snprintf(&buffer[length], COLS*20 - length, "."); + snprintf(&buffer[length], COLS * 20 - length, "."); return folded; } @@ -3109,14 +2974,13 @@ void capitalizeAndPunctuateSentences(char *text, short length) { newSentence = true; - for (i = 0; i + 1 < length && text[i] != '\0' && text[i+1] != '\0'; i++) { + for (i = 0; i + 1 < length && text[i] != '\0' && text[i + 1] != '\0'; i++) { if (text[i] == COLOR_ESCAPE) { i += 3; // the loop increment will get the last byte - } else if (text[i] == '"' - && (text[i+1] == '.' || text[i+1] == ',')) { + } else if (text[i] == '"' && (text[i + 1] == '.' || text[i + 1] == ',')) { // Implement the American quotation mark/period/comma ordering rule. - text[i] = text[i+1]; - text[i+1] = '"'; + text[i] = text[i + 1]; + text[i + 1] = '"'; } else if (text[i] == '\n') { newSentence = true; } else if (newSentence) { @@ -3127,9 +2991,9 @@ void capitalizeAndPunctuateSentences(char *text, short length) { } // Copy \n-delimited lines to the given buffer. Carry colors across line breaks. -void splitLines(short lines, char wrapped[COLS*20], char buffer[][COLS*2], short bufferCursor) { +void splitLines(short lines, char wrapped[COLS * 20], char buffer[][COLS * 2], short bufferCursor) { short linesSeen; - char color[5], line[COLS*2]; + char color[5], line[COLS * 2]; char *start, *end; start = &(wrapped[0]); @@ -3146,9 +3010,9 @@ void splitLines(short lines, char wrapped[COLS*20], char buffer[][COLS*2], short if (bufferCursor + 1 - lines + linesSeen >= 0) { strncpy(line, color, 5); - strncat(line, start, COLS*2 - strlen(line) - 1); - line[COLS*2-1] = '\0'; - strncpy(buffer[bufferCursor + 1 - lines + linesSeen], line, COLS*2); + strncat(line, start, COLS * 2 - strlen(line) - 1); + line[COLS * 2 - 1] = '\0'; + strncpy(buffer[bufferCursor + 1 - lines + linesSeen], line, COLS * 2); line[0] = '\0'; } @@ -3158,9 +3022,9 @@ void splitLines(short lines, char wrapped[COLS*20], char buffer[][COLS*2], short } strncpy(line, color, 5); - strncat(line, start, COLS*2 - strlen(line) - 1); - line[COLS*2-1] = '\0'; - strncpy(buffer[bufferCursor], line, COLS*2); + strncat(line, start, COLS * 2 - strlen(line) - 1); + line[COLS * 2 - 1] = '\0'; + strncpy(buffer[bufferCursor], line, COLS * 2); } // Fill the buffer of height lines with archived messages. Fill from the @@ -3169,10 +3033,10 @@ void splitLines(short lines, char wrapped[COLS*20], char buffer[][COLS*2], short // (rows of buffer filled) // latestMessageLines, if not null, is filled with the number of formatted // lines generated by events from the current player turn. -void formatRecentMessages(char buffer[][COLS*2], size_t height, short *linesFormatted, short *latestMessageLines) { +void formatRecentMessages(char buffer[][COLS * 2], size_t height, short *linesFormatted, short *latestMessageLines) { short lines, bufferCursor, messagesFolded, messagesFormatted; unsigned long turn; - char folded[COLS*20], wrapped[COLS*20]; + char folded[COLS * 20], wrapped[COLS * 20]; bufferCursor = height - 1; messagesFormatted = 0; @@ -3187,7 +3051,7 @@ void formatRecentMessages(char buffer[][COLS*2], size_t height, short *linesForm break; } - capitalizeAndPunctuateSentences(folded, COLS*20); + capitalizeAndPunctuateSentences(folded, COLS * 20); lines = wrapText(wrapped, folded, DCOLS); splitLines(lines, wrapped, buffer, bufferCursor); @@ -3211,7 +3075,7 @@ void formatRecentMessages(char buffer[][COLS*2], size_t height, short *linesForm // Display recent archived messages after recalculating message confirmations. void displayRecentMessages() { short i; - char messageBuffer[MESSAGE_LINES][COLS*2]; + char messageBuffer[MESSAGE_LINES][COLS * 2]; formatRecentMessages(messageBuffer, MESSAGE_LINES, 0, &messagesUnconfirmed); @@ -3228,7 +3092,7 @@ void displayRecentMessages() { // offset: index of oldest (visually highest) message to draw // height: height in rows of the message archive display area // rbuf: background display buffer to draw against -void drawMessageArchive(char messages[MESSAGE_ARCHIVE_LINES][COLS*2], short length, short offset, short height, cellDisplayBuffer rbuf[COLS][ROWS]) { +void drawMessageArchive(char messages[MESSAGE_ARCHIVE_LINES][COLS * 2], short length, short offset, short height, cellDisplayBuffer rbuf[COLS][ROWS]) { int i, j, k, fadePercent; cellDisplayBuffer dbuf[COLS][ROWS]; @@ -3237,12 +3101,13 @@ void drawMessageArchive(char messages[MESSAGE_ARCHIVE_LINES][COLS*2], short leng for (i = 0; (MESSAGE_ARCHIVE_LINES - offset + i) < MESSAGE_ARCHIVE_LINES && i < ROWS && i < height; i++) { printString(messages[MESSAGE_ARCHIVE_LINES - offset + i], mapToWindowX(0), i, &white, &black, dbuf); - // Set the dbuf opacity, and do a fade from bottom to top to make it clear that the bottom messages are the most recent. + // Set the dbuf opacity, and do a fade from bottom to top to make it clear that the bottom messages are the most + // recent. fadePercent = 50 * (length - offset + i) / length + 50; for (j = 0; j < DCOLS; j++) { dbuf[mapToWindowX(j)][i].opacity = INTERFACE_OPACITY; if (dbuf[mapToWindowX(j)][i].character != ' ') { - for (k=0; k<3; k++) { + for (k = 0; k < 3; k++) { dbuf[mapToWindowX(j)][i].foreColorComponents[k] = dbuf[mapToWindowX(j)][i].foreColorComponents[k] * fadePercent / 100; } } @@ -3260,15 +3125,13 @@ void drawMessageArchive(char messages[MESSAGE_ARCHIVE_LINES][COLS*2], short leng // offset: index of oldest (visually highest) message to draw in the fully expanded state // height: height in rows of the message archive display area in the fully expanded state // rbuf: background display buffer to draw against -void animateMessageArchive(boolean opening, char messages[MESSAGE_ARCHIVE_LINES][COLS*2], short length, short offset, short height, cellDisplayBuffer rbuf[COLS][ROWS]) { +void animateMessageArchive(boolean opening, char messages[MESSAGE_ARCHIVE_LINES][COLS * 2], short length, short offset, short height, cellDisplayBuffer rbuf[COLS][ROWS]) { short i; boolean fastForward; fastForward = false; - for (i = (opening ? MESSAGE_LINES : height); - (opening ? i <= height : i >= MESSAGE_LINES); - i += (opening ? 1 : -1)) { + for (i = (opening ? MESSAGE_LINES : height); (opening ? i <= height : i >= MESSAGE_LINES); i += (opening ? 1 : -1)) { drawMessageArchive(messages, length, offset - height + i, i, rbuf); @@ -3288,7 +3151,7 @@ void animateMessageArchive(boolean opening, char messages[MESSAGE_ARCHIVE_LINES] // rbuf: background display buffer to draw against // // returns the new offset, which can change if the player scrolled around before closing -short scrollMessageArchive(char messages[MESSAGE_ARCHIVE_LINES][COLS*2], short length, short offset, short height, cellDisplayBuffer rbuf[COLS][ROWS]) { +short scrollMessageArchive(char messages[MESSAGE_ARCHIVE_LINES][COLS * 2], short length, short offset, short height, cellDisplayBuffer rbuf[COLS][ROWS]) { short lastOffset; boolean exit; rogueEvent theEvent; @@ -3355,7 +3218,7 @@ short scrollMessageArchive(char messages[MESSAGE_ARCHIVE_LINES][COLS*2], short l void displayMessageArchive() { short length, offset, height; cellDisplayBuffer rbuf[COLS][ROWS]; - char messageBuffer[MESSAGE_ARCHIVE_LINES][COLS*2]; + char messageBuffer[MESSAGE_ARCHIVE_LINES][COLS * 2]; formatRecentMessages(messageBuffer, MESSAGE_ARCHIVE_LINES, &length, 0); @@ -3388,7 +3251,7 @@ void temporaryMessage(const char *msg, unsigned long flags) { assureCosmeticRNG; strcpy(message, msg); - for (i=0; message[i] == COLOR_ESCAPE; i += 4) { + for (i = 0; message[i] == COLOR_ESCAPE; i += 4) { upperCase(&(message[i])); } @@ -3396,9 +3259,9 @@ void temporaryMessage(const char *msg, unsigned long flags) { refreshSideBar(-1, -1, false); } - for (i=0; i 0) { - printString("--MORE--", COLS - 8, MESSAGE_LINES-1, &black, &white, 0); + printString("--MORE--", COLS - 8, MESSAGE_LINES - 1, &black, &white, 0); } else { printString("--MORE--", COLS - 8, MESSAGE_LINES, &black, &white, 0); } @@ -3532,13 +3396,13 @@ void displayMoreSign() { } if (strLenWithoutEscapes(displayedMessage[0]) < DCOLS - 8 || messagesUnconfirmed > 0) { - printString("--MORE--", COLS - 8, MESSAGE_LINES-1, &black, &white, 0); + printString("--MORE--", COLS - 8, MESSAGE_LINES - 1, &black, &white, 0); waitForAcknowledgment(); - printString(" ", COLS - 8, MESSAGE_LINES-1, &black, &black, 0); + printString(" ", COLS - 8, MESSAGE_LINES - 1, &black, &black, 0); } else { printString("--MORE--", COLS - 8, MESSAGE_LINES, &black, &white, 0); waitForAcknowledgment(); - for (i=1; i<=8; i++) { + for (i = 1; i <= 8; i++) { refreshDungeonCell(DCOLS - i, 0); } } @@ -3555,16 +3419,16 @@ short encodeMessageColor(char *msg, short i, const color *theColor) { bakeColor(&col); - col.red = clamp(col.red, 0, 100); - col.green = clamp(col.green, 0, 100); - col.blue = clamp(col.blue, 0, 100); + col.red = clamp(col.red, 0, 100); + col.green = clamp(col.green, 0, 100); + col.blue = clamp(col.blue, 0, 100); needTerminator = !msg[i] || !msg[i + 1] || !msg[i + 2] || !msg[i + 3]; msg[i++] = COLOR_ESCAPE; - msg[i++] = (char) (COLOR_VALUE_INTERCEPT + col.red); - msg[i++] = (char) (COLOR_VALUE_INTERCEPT + col.green); - msg[i++] = (char) (COLOR_VALUE_INTERCEPT + col.blue); + msg[i++] = (char)(COLOR_VALUE_INTERCEPT + col.red); + msg[i++] = (char)(COLOR_VALUE_INTERCEPT + col.green); + msg[i++] = (char)(COLOR_VALUE_INTERCEPT + col.blue); if (needTerminator) { msg[i] = '\0'; @@ -3585,13 +3449,13 @@ short decodeMessageColor(const char *msg, short i, color *returnColor) { } else { i++; *returnColor = black; - returnColor->red = (short) (msg[i++] - COLOR_VALUE_INTERCEPT); - returnColor->green = (short) (msg[i++] - COLOR_VALUE_INTERCEPT); - returnColor->blue = (short) (msg[i++] - COLOR_VALUE_INTERCEPT); + returnColor->red = (short)(msg[i++] - COLOR_VALUE_INTERCEPT); + returnColor->green = (short)(msg[i++] - COLOR_VALUE_INTERCEPT); + returnColor->blue = (short)(msg[i++] - COLOR_VALUE_INTERCEPT); - returnColor->red = clamp(returnColor->red, 0, 100); - returnColor->green = clamp(returnColor->green, 0, 100); - returnColor->blue = clamp(returnColor->blue, 0, 100); + returnColor->red = clamp(returnColor->red, 0, 100); + returnColor->green = clamp(returnColor->green, 0, 100); + returnColor->blue = clamp(returnColor->blue, 0, 100); } return i; } @@ -3615,7 +3479,7 @@ void updateMessageDisplay() { short i, j, m; color messageColor; - for (i=0; i= messagesUnconfirmed) { @@ -3626,19 +3490,18 @@ void updateMessageDisplay() { for (j = m = 0; displayedMessage[i][m] && j < DCOLS; j++, m++) { while (displayedMessage[i][m] == COLOR_ESCAPE) { - m = decodeMessageColor(displayedMessage[i], m, &messageColor); // pulls the message color out and advances m + m = decodeMessageColor(displayedMessage[i], m, + &messageColor); // pulls the message color out and advances m if (i >= messagesUnconfirmed) { applyColorAverage(&messageColor, &black, 50); applyColorAverage(&messageColor, &black, 75 * i / MESSAGE_LINES); } } - plotCharWithColor(displayedMessage[i][m], (windowpos){ mapToWindowX(j), MESSAGE_LINES - i - 1 }, - &messageColor, - &black); + plotCharWithColor(displayedMessage[i][m], (windowpos){mapToWindowX(j), MESSAGE_LINES - i - 1}, &messageColor, &black); } for (; j < DCOLS; j++) { - plotCharWithColor(' ', (windowpos){ mapToWindowX(j), MESSAGE_LINES - i - 1 }, &black, &black); + plotCharWithColor(' ', (windowpos){mapToWindowX(j), MESSAGE_LINES - i - 1}, &black, &black); } } } @@ -3646,7 +3509,7 @@ void updateMessageDisplay() { // Does NOT clear the message archive. void deleteMessages() { short i; - for (i=0; iloc.x][monst->loc.y] - && !(monst->info.flags & MONST_NOT_LISTED_IN_SIDEBAR) + if ((canDirectlySeeMonster(monst) || (indirectVision && (canSeeMonster(monst) || rogue.playbackOmniscience))) && !addedEntity[monst->loc.x][monst->loc.y] && !(monst->info.flags & MONST_NOT_LISTED_IN_SIDEBAR) && (px - monst->loc.x) * (px - monst->loc.x) + (py - monst->loc.y) * (py - monst->loc.y) < shortestDistance) { shortestDistance = (px - monst->loc.x) * (px - monst->loc.x) + (py - monst->loc.y) * (py - monst->loc.y); @@ -3812,8 +3665,7 @@ void refreshSideBar(short focusX, short focusY, boolean focusedEntityMustGoFirst do { shortestDistance = 10000; for (theItem = floorItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { - if ((playerCanDirectlySee(theItem->loc.x, theItem->loc.y) || (indirectVision && (playerCanSeeOrSense(theItem->loc.x, theItem->loc.y) || rogue.playbackOmniscience))) - && !addedEntity[theItem->loc.x][theItem->loc.y] + if ((playerCanDirectlySee(theItem->loc.x, theItem->loc.y) || (indirectVision && (playerCanSeeOrSense(theItem->loc.x, theItem->loc.y) || rogue.playbackOmniscience))) && !addedEntity[theItem->loc.x][theItem->loc.y] && (px - theItem->loc.x) * (px - theItem->loc.x) + (py - theItem->loc.y) * (py - theItem->loc.y) < shortestDistance) { shortestDistance = (px - theItem->loc.x) * (px - theItem->loc.x) + (py - theItem->loc.y) * (py - theItem->loc.y); @@ -3831,69 +3683,56 @@ void refreshSideBar(short focusX, short focusY, boolean focusedEntityMustGoFirst // Non-focused terrain. // count up the number of candidate locations - for (k=0; k= ROWS - 1) goto no_space_for_more_entities; - if (coordinatesAreInMap(i, j) - && !addedEntity[i][j] - && cellHasTMFlag(i, j, TM_LIST_IN_SIDEBAR) - && (playerCanDirectlySee(i, j) || (indirectVision && (playerCanSeeOrSense(i, j) || rogue.playbackOmniscience)))) { + if (coordinatesAreInMap(i, j) && !addedEntity[i][j] && cellHasTMFlag(i, j, TM_LIST_IN_SIDEBAR) && (playerCanDirectlySee(i, j) || (indirectVision && (playerCanSeeOrSense(i, j) || rogue.playbackOmniscience)))) { addedEntity[i][j] = true; entityList[displayEntityCount] = tileCatalog[pmap[i][j].layers[layerWithTMFlag(i, j, TM_LIST_IN_SIDEBAR)]].description; entityType[displayEntityCount] = EDT_TERRAIN; - terrainLocationMap[displayEntityCount] = (pos) { i, j }; + terrainLocationMap[displayEntityCount] = (pos){i, j}; displayEntityCount++; } } } } - no_space_for_more_entities:; + no_space_for_more_entities:; } // Entities are now listed. Start printing. - for (i=0; iloc.x; - y = ((creature *) entityList[i])->loc.y; - printY = printMonsterInfo((creature *) entityList[i], - printY, - (focusEntity && (x != focusX || y != focusY)), - (x == focusX && y == focusY)); + x = ((creature *)entityList[i])->loc.x; + y = ((creature *)entityList[i])->loc.y; + printY = printMonsterInfo((creature *)entityList[i], printY, (focusEntity && (x != focusX || y != focusY)), (x == focusX && y == focusY)); } else if (entityType[i] == EDT_ITEM) { - x = ((item *) entityList[i])->loc.x; - y = ((item *) entityList[i])->loc.y; - printY = printItemInfo((item *) entityList[i], - printY, - (focusEntity && (x != focusX || y != focusY)), - (x == focusX && y == focusY)); + x = ((item *)entityList[i])->loc.x; + y = ((item *)entityList[i])->loc.y; + printY = printItemInfo((item *)entityList[i], printY, (focusEntity && (x != focusX || y != focusY)), (x == focusX && y == focusY)); } else if (entityType[i] == EDT_TERRAIN) { x = terrainLocationMap[i].x; y = terrainLocationMap[i].y; - printY = printTerrainInfo(x, y, - printY, - ((const char *) entityList[i]), - (focusEntity && (x != focusX || y != focusY)), - (x == focusX && y == focusY)); + printY = printTerrainInfo(x, y, printY, ((const char *)entityList[i]), (focusEntity && (x != focusX || y != focusY)), (x == focusX && y == focusY)); } if (focusEntity && (x == focusX && y == focusY) && printY < ROWS) { gotFocusedEntityOnScreen = true; } - for (j=oldPrintY; j= width - 1) { - nextChar = i+1; + nextChar = i + 1; while (sourceText[nextChar] == COLOR_ESCAPE) { nextChar += 4; } @@ -3970,7 +3809,7 @@ short wrapText(char *to, const char *sourceText, short width) { char printString[COLS * ROWS * 2]; short spaceLeftOnLine, wordWidth; - strcpy(printString, sourceText); // a copy we can write on + strcpy(printString, sourceText); // a copy we can write on breakUpLongWordsIn(printString, width, true); // break up any words that are wider than the width. textLength = strlen(printString); // do NOT discount escape sequences @@ -3979,7 +3818,8 @@ short wrapText(char *to, const char *sourceText, short width) { // Now go through and replace spaces with newlines as needed. // Fast foward until i points to the first character that is not a color escape. - for (i=0; printString[i] == COLOR_ESCAPE; i+= 4); + for (i = 0; printString[i] == COLOR_ESCAPE; i += 4) + ; spaceLeftOnLine = width; while (i < textLength) { @@ -3999,7 +3839,7 @@ short wrapText(char *to, const char *sourceText, short width) { printString[i] = '\n'; lineCount++; spaceLeftOnLine = width - wordWidth; // line width minus the width of the word we just wrapped - //printf("\n\n%s", printString); + // printf("\n\n%s", printString); } else { spaceLeftOnLine -= 1 + wordWidth; } @@ -4012,8 +3852,7 @@ short wrapText(char *to, const char *sourceText, short width) { } // returns the y-coordinate of the last line -short printStringWithWrapping(const char *theString, short x, short y, short width, const color *foreColor, - const color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]) { +short printStringWithWrapping(const char *theString, short x, short y, short width, const color *foreColor, const color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]) { color fColor; char printString[COLS * ROWS * 2]; short i, px, py; @@ -4021,15 +3860,15 @@ short printStringWithWrapping(const char *theString, short x, short y, short wid wrapText(printString, theString, width); // inserts newlines as necessary // display the string - px = x; //px and py are the print insertion coordinates; x and y remain the top-left of the text box + px = x; // px and py are the print insertion coordinates; x and y remain the top-left of the text box py = y; fColor = *foreColor; - for (i=0; printString[i] != '\0'; i++) { + for (i = 0; printString[i] != '\0'; i++) { if (printString[i] == '\n') { - px = x; // back to the leftmost column + px = x; // back to the leftmost column if (py < ROWS - 1) { // don't advance below the bottom of the screen - py++; // next line + py++; // next line } else { break; // If we've run out of room, stop. } @@ -4039,8 +3878,8 @@ short printStringWithWrapping(const char *theString, short x, short y, short wid continue; } - if (locIsInWindow((windowpos){ px, py })) { - plotCharToBuffer(printString[i], (windowpos){ px, py }, &fColor, backColor, dbuf); + if (locIsInWindow((windowpos){px, py})) { + plotCharToBuffer(printString[i], (windowpos){px, py}, &fColor, backColor, dbuf); } px++; @@ -4056,50 +3895,48 @@ char nextKeyPress(boolean textInput) { return theEvent.param1; } -#define BROGUE_HELP_LINE_COUNT 33 +#define BROGUE_HELP_LINE_COUNT 33 void printHelpScreen() { short i, j; cellDisplayBuffer dbuf[COLS][ROWS], rbuf[COLS][ROWS]; - char helpText[BROGUE_HELP_LINE_COUNT][DCOLS*3] = { - "", - "", - " -- Commands --", - "", - " mouse ****move cursor (including to examine monsters and terrain)", - " click ****travel", - " control-click ****advance one space", - " ****enable keyboard cursor control", - " ****disable keyboard cursor control", - "hjklyubn, arrow keys, or numpad ****move or attack (control or shift to run)", - "", - "a/e/r/t/d/c/R/w ****apply/equip/remove/throw/drop/call/relabel/swap an item", - " T ****re-throw last item at last monster", - " i, right-click ****view inventory", - " D ****list discovered items", - "", - " z ****rest once", - " Z ****rest for 100 turns or until something happens", - " s ****search for secrets (control-s: long search)", - " <, > ****travel to stairs", - " x ****auto-explore (control-x: fast forward)", - " A ****autopilot (control-A: fast forward)", - " M ****display old messages", - " G ****toggle graphical tiles (when available)", - "", - " S ****save and exit", - " Q ****quit and abandon game", - "", - " \\ ****disable/enable color effects", - " ] ****display/hide stealth range", - " ****clear message or cancel command", - "", - " -- press space or click to continue --" - }; + char helpText[BROGUE_HELP_LINE_COUNT][DCOLS * 3] = {"", + "", + " -- Commands --", + "", + " mouse ****move cursor (including to examine monsters and terrain)", + " click ****travel", + " control-click ****advance one space", + " ****enable keyboard cursor control", + " ****disable keyboard cursor control", + "hjklyubn, arrow keys, or numpad ****move or attack (control or shift to run)", + "", + "a/e/r/t/d/c/R/w ****apply/equip/remove/throw/drop/call/relabel/swap an item", + " T ****re-throw last item at last monster", + " i, right-click ****view inventory", + " D ****list discovered items", + "", + " z ****rest once", + " Z ****rest for 100 turns or until something happens", + " s ****search for secrets (control-s: long search)", + " <, > ****travel to stairs", + " x ****auto-explore (control-x: fast forward)", + " A ****autopilot (control-A: fast forward)", + " M ****display old messages", + " G ****toggle graphical tiles (when available)", + "", + " S ****save and exit", + " Q ****quit and abandon game", + "", + " \\ ****disable/enable color effects", + " ] ****display/hide stealth range", + " ****clear message or cancel command", + "", + " -- press space or click to continue --"}; // Replace the "****"s with color escapes. - for (i=0; i 0 - && totalFrequency > 0) { + if (!theTable[i].identified && theTable[i].frequency > 0 && totalFrequency > 0) { sprintf(buf2, " (%i%%)", theTable[i].frequency * 100 / totalFrequency); strcat(buf, buf2); @@ -4198,11 +4033,10 @@ void printDiscoveriesScreen() { printString("-- WANDS --", mapToWindowX(53), y += NUMBER_STAFF_KINDS + 1, &flavorTextColor, &black, dbuf); printDiscoveries(WAND, gameConst->numberWandKinds, G_WAND, mapToWindowX(54), ++y, dbuf); - printString(KEYBOARD_LABELS ? "-- press any key to continue --" : "-- touch anywhere to continue --", - mapToWindowX(20), mapToWindowY(DROWS-2), &itemMessageColor, &black, dbuf); + printString(KEYBOARD_LABELS ? "-- press any key to continue --" : "-- touch anywhere to continue --", mapToWindowX(20), mapToWindowY(DROWS - 2), &itemMessageColor, &black, dbuf); - for (i=0; i topRange) { topRange = map[i][j]; - //if (topRange == 0) { - //printf("\ntop is zero at %i,%i", i, j); + // if (topRange == 0) { + // printf("\ntop is zero at %i,%i", i, j); //} } if (map[i][j] < bottomRange) { @@ -4304,11 +4137,9 @@ void displayGrid(short **map) { } } - for (i=0; i= ROWS - 1) { @@ -4474,7 +4271,7 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight) oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; if (y < ROWS - 1) { printString(" ", 0, y, &white, &black, 0); // Start with a blank line @@ -4496,9 +4293,9 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight) applyColorAugment(&monstForeColor, &black, 100); applyColorAugment(&monstBackColor, &black, 100); } - plotCharWithColor(monstChar, (windowpos){ 0, y }, &monstForeColor, &monstBackColor); - if(monst->carriedItem) { - plotCharWithColor(monst->carriedItem->displayChar, (windowpos) { 1, y }, &itemColor, &black); + plotCharWithColor(monstChar, (windowpos){0, y}, &monstForeColor, &monstBackColor); + if (monst->carriedItem) { + plotCharWithColor(monst->carriedItem->displayChar, (windowpos){1, y}, &itemColor, &black); } monsterName(monstName, monst, false); upperCase(monstName); @@ -4510,25 +4307,23 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight) strcat(monstName, "(invisible)"); } else if (playerInDarkness()) { strcat(monstName, " xxxx"); - //encodeMessageColor(monstName, strlen(monstName) - 4, &playerInDarknessColor); + // encodeMessageColor(monstName, strlen(monstName) - 4, &playerInDarknessColor); encodeMessageColor(monstName, strlen(monstName) - 4, &monstForeColor); strcat(monstName, "(dark)"); } else if (!(pmapAt(player.loc)->flags & IS_IN_SHADOW)) { strcat(monstName, " xxxx"); - //encodeMessageColor(monstName, strlen(monstName) - 4, &playerInLightColor); + // encodeMessageColor(monstName, strlen(monstName) - 4, &playerInLightColor); encodeMessageColor(monstName, strlen(monstName) - 4, &monstForeColor); strcat(monstName, "(lit)"); } } sprintf(buf, ": %s", monstName); - printString(buf, monst->carriedItem?2:1, y++, (dim ? &gray : &white), &black, 0); + printString(buf, monst->carriedItem ? 2 : 1, y++, (dim ? &gray : &white), &black, 0); } // mutation, if any - if (y < ROWS - 1 - && monst->mutationIndex >= 0 - && (!player.status[STATUS_HALLUCINATING] || rogue.playbackOmniscience)) { + if (y < ROWS - 1 && monst->mutationIndex >= 0 && (!player.status[STATUS_HALLUCINATING] || rogue.playbackOmniscience)) { strcpy(buf, " "); sprintf(buf2, "xxxx(%s)", mutationCatalog[monst->mutationIndex].title); @@ -4546,8 +4341,7 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight) } // hit points - if (monst->info.maxHP > 1 - && !(monst->info.flags & MONST_INVULNERABLE)) { + if (monst->info.maxHP > 1 && !(monst->info.flags & MONST_INVULNERABLE)) { if (monst == &player) { healthBarColor = redBar; @@ -4585,15 +4379,13 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight) if (!player.status[STATUS_HALLUCINATING] || rogue.playbackOmniscience || monst == &player) { - for (i=0; istatus[i] > 0) { sprintf(buf, "%s%i", statusStrings[STATUS_WEAKENED], monst->weaknessAmount); printProgressBar(0, y++, buf, monst->status[i], monst->maxStatus[i], &redBar, dim); } else if (i == STATUS_LEVITATING && monst->status[i] > 0) { printProgressBar(0, y++, (monst == &player ? "Levitating" : "Flying"), monst->status[i], monst->maxStatus[i], &redBar, dim); - } else if (i == STATUS_POISONED - && monst->status[i] > 0) { - + } else if (i == STATUS_POISONED && monst->status[i] > 0) { if (monst->status[i] * monst->poisonAmount >= monst->currentHP) { strcpy(buf, "Fatal Poison"); @@ -4603,9 +4395,7 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight) if (monst->poisonAmount == 1) { printProgressBar(0, y++, buf, monst->status[i], monst->maxStatus[i], &redBar, dim); } else { - sprintf(buf2, "%s (x%i)", - buf, - monst->poisonAmount); + sprintf(buf2, "%s (x%i)", buf, monst->poisonAmount); printProgressBar(0, y++, buf2, monst->status[i], monst->maxStatus[i], &redBar, dim); } } else if (statusStrings[i][0] && monst->status[i] > 0) { @@ -4613,116 +4403,99 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight) } } if (posEq(monst->targetCorpseLoc, monst->loc)) { - printProgressBar(0, y++, monsterText[monst->info.monsterID].absorbStatus, monst->corpseAbsorptionCounter, 20, &redBar, dim); + printProgressBar(0, y++, monsterText[monst->info.monsterID].absorbStatus, monst->corpseAbsorptionCounter, 20, &redBar, dim); } } - if (monst != &player - && (!(monst->info.flags & MONST_INANIMATE) - || monst->creatureState == MONSTER_ALLY)) { + if (monst != &player && (!(monst->info.flags & MONST_INANIMATE) || monst->creatureState == MONSTER_ALLY)) { - if (y < ROWS - 1) { - if (monst->wasNegated - && monst->newPowerCount == monst->totalPowerCount - && y < ROWS - 1 - && (!player.status[STATUS_HALLUCINATING] || rogue.playbackOmniscience )) { - printString(" Negated ", 0, y++, (dim ? &darkPink : &pink), &black, 0); - } - if (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience && y < ROWS - 1) { - printString(hallucinationStrings[rand_range(0, 9)], 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if (monst->bookkeepingFlags & MB_CAPTIVE && y < ROWS - 1) { - printString(" (Captive) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if ((monst->info.flags & MONST_RESTRICTED_TO_LIQUID) - && !cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING)) { - printString(" (Helpless) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if (monst->creatureState == MONSTER_SLEEPING && y < ROWS - 1) { - printString(" (Sleeping) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if ((monst->creatureState == MONSTER_ALLY) && y < ROWS - 1) { - printString(" (Ally) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if (monst->creatureState == MONSTER_FLEEING && y < ROWS - 1) { - printString(" (Fleeing) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if ((monst->creatureState == MONSTER_WANDERING) && y < ROWS - 1) { - if ((monst->bookkeepingFlags & MB_FOLLOWER) && monst->leader && (monst->leader->info.flags & MONST_IMMOBILE)) { - // follower of an immobile leader -- i.e. a totem - printString(" (Worshiping) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if ((monst->bookkeepingFlags & MB_FOLLOWER) && monst->leader && (monst->leader->bookkeepingFlags & MB_CAPTIVE)) { - // actually a captor/torturer - printString(" (Guarding) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else { - printString(" (Wandering) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } - } else if (monst->ticksUntilTurn > max(0, player.ticksUntilTurn) + player.movementSpeed) { - printString(" (Off balance) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } else if ((monst->creatureState == MONSTER_TRACKING_SCENT) && y < ROWS - 1) { - printString(" (Hunting) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); - } + if (y < ROWS - 1) { + if (monst->wasNegated && monst->newPowerCount == monst->totalPowerCount && y < ROWS - 1 && (!player.status[STATUS_HALLUCINATING] || rogue.playbackOmniscience)) { + printString(" Negated ", 0, y++, (dim ? &darkPink : &pink), &black, 0); } - } else if (monst == &player) { - if (y < ROWS - 1) { - tempColorEscape[0] = '\0'; - grayColorEscape[0] = '\0'; - if (player.status[STATUS_WEAKENED]) { - tempColor = red; - if (dim) { - applyColorAverage(&tempColor, &black, 50); - } - encodeMessageColor(tempColorEscape, 0, &tempColor); - encodeMessageColor(grayColorEscape, 0, (dim ? &darkGray : &gray)); - } - - if (!rogue.armor || rogue.armor->flags & ITEM_IDENTIFIED || rogue.playbackOmniscience) { - - sprintf(buf, "Str: %s%i%s Armor: %i", - tempColorEscape, - rogue.strength - player.weaknessAmount, - grayColorEscape, - displayedArmorValue()); + if (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience && y < ROWS - 1) { + printString(hallucinationStrings[rand_range(0, 9)], 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if (monst->bookkeepingFlags & MB_CAPTIVE && y < ROWS - 1) { + printString(" (Captive) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if ((monst->info.flags & MONST_RESTRICTED_TO_LIQUID) && !cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING)) { + printString(" (Helpless) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if (monst->creatureState == MONSTER_SLEEPING && y < ROWS - 1) { + printString(" (Sleeping) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if ((monst->creatureState == MONSTER_ALLY) && y < ROWS - 1) { + printString(" (Ally) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if (monst->creatureState == MONSTER_FLEEING && y < ROWS - 1) { + printString(" (Fleeing) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if ((monst->creatureState == MONSTER_WANDERING) && y < ROWS - 1) { + if ((monst->bookkeepingFlags & MB_FOLLOWER) && monst->leader && (monst->leader->info.flags & MONST_IMMOBILE)) { + // follower of an immobile leader -- i.e. a totem + printString(" (Worshiping) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if ((monst->bookkeepingFlags & MB_FOLLOWER) && monst->leader && (monst->leader->bookkeepingFlags & MB_CAPTIVE)) { + // actually a captor/torturer + printString(" (Guarding) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); } else { - sprintf(buf, "Str: %s%i%s Armor: %i?", - tempColorEscape, - rogue.strength - player.weaknessAmount, - grayColorEscape, - estimatedArmorValue()); + printString(" (Wandering) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); } - //buf[20] = '\0'; - printString(" ", 0, y, &white, &black, 0); - printString(buf, (20 - strLenWithoutEscapes(buf)) / 2, y++, (dim ? &darkGray : &gray), &black, 0); + } else if (monst->ticksUntilTurn > max(0, player.ticksUntilTurn) + player.movementSpeed) { + printString(" (Off balance) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); + } else if ((monst->creatureState == MONSTER_TRACKING_SCENT) && y < ROWS - 1) { + printString(" (Hunting) ", 0, y++, (dim ? &darkGray : &gray), &black, 0); } - if (y < ROWS - 1 && rogue.gold) { - sprintf(buf, "Gold: %li", rogue.gold); - buf[20] = '\0'; - printString(" ", 0, y, &white, &black, 0); - printString(buf, (20 - strLenWithoutEscapes(buf)) / 2, y++, (dim ? &darkGray : &gray), &black, 0); - } - if (y < ROWS - 1) { - tempColorEscape[0] = '\0'; - grayColorEscape[0] = '\0'; - tempColor = playerInShadowColor; - percent = (rogue.stealthRange - 2) * 100 / 28; - applyColorAverage(&tempColor, &black, percent); - applyColorAugment(&tempColor, &playerInLightColor, percent); + } + } else if (monst == &player) { + if (y < ROWS - 1) { + tempColorEscape[0] = '\0'; + grayColorEscape[0] = '\0'; + if (player.status[STATUS_WEAKENED]) { + tempColor = red; if (dim) { applyColorAverage(&tempColor, &black, 50); } encodeMessageColor(tempColorEscape, 0, &tempColor); encodeMessageColor(grayColorEscape, 0, (dim ? &darkGray : &gray)); - sprintf(buf, "%sStealth range: %i%s", - tempColorEscape, - rogue.stealthRange, - grayColorEscape); - printString(" ", 0, y, &white, &black, 0); - printString(buf, 1, y++, (dim ? &darkGray : &gray), &black, 0); } + + if (!rogue.armor || rogue.armor->flags & ITEM_IDENTIFIED || rogue.playbackOmniscience) { + + sprintf(buf, "Str: %s%i%s Armor: %i", tempColorEscape, rogue.strength - player.weaknessAmount, grayColorEscape, displayedArmorValue()); + } else { + sprintf(buf, "Str: %s%i%s Armor: %i?", tempColorEscape, rogue.strength - player.weaknessAmount, grayColorEscape, estimatedArmorValue()); + } + // buf[20] = '\0'; + printString(" ", 0, y, &white, &black, 0); + printString(buf, (20 - strLenWithoutEscapes(buf)) / 2, y++, (dim ? &darkGray : &gray), &black, 0); + } + if (y < ROWS - 1 && rogue.gold) { + sprintf(buf, "Gold: %li", rogue.gold); + buf[20] = '\0'; + printString(" ", 0, y, &white, &black, 0); + printString(buf, (20 - strLenWithoutEscapes(buf)) / 2, y++, (dim ? &darkGray : &gray), &black, 0); + } + if (y < ROWS - 1) { + tempColorEscape[0] = '\0'; + grayColorEscape[0] = '\0'; + tempColor = playerInShadowColor; + percent = (rogue.stealthRange - 2) * 100 / 28; + applyColorAverage(&tempColor, &black, percent); + applyColorAugment(&tempColor, &playerInLightColor, percent); + if (dim) { + applyColorAverage(&tempColor, &black, 50); + } + encodeMessageColor(tempColorEscape, 0, &tempColor); + encodeMessageColor(grayColorEscape, 0, (dim ? &darkGray : &gray)); + sprintf(buf, "%sStealth range: %i%s", tempColorEscape, rogue.stealthRange, grayColorEscape); + printString(" ", 0, y, &white, &black, 0); + printString(buf, 1, y++, (dim ? &darkGray : &gray), &black, 0); } + } if (y < ROWS - 1) { printString(" ", 0, y++, (dim ? &darkGray : &gray), &black, 0); } if (highlight) { - for (i=0; i<20; i++) { - highlightStrength = smoothHiliteGradient(i, 20-1) / 10; - for (j=initialY; j < (y == ROWS - 1 ? y : min(y - 1, ROWS - 1)); j++) { + for (i = 0; i < 20; i++) { + highlightStrength = smoothHiliteGradient(i, 20 - 1) / 10; + for (j = initialY; j < (y == ROWS - 1 ? y : min(y - 1, ROWS - 1)); j++) { highlightScreenCell(i, j, &white, highlightStrength); } } @@ -4761,7 +4534,7 @@ short printItemInfo(item *theItem, short y, boolean dim, boolean highlight) { oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; if (y < ROWS - 1) { // Unhighlight if it's highlighted as part of the path. @@ -4777,7 +4550,7 @@ short printItemInfo(item *theItem, short y, boolean dim, boolean highlight) { applyColorAverage(&itemForeColor, &black, 50); applyColorAverage(&itemBackColor, &black, 50); } - plotCharWithColor(itemChar, (windowpos){ 0, y }, &itemForeColor, &itemBackColor); + plotCharWithColor(itemChar, (windowpos){0, y}, &itemForeColor, &itemBackColor); printString(": ", 1, y, (dim ? &gray : &white), &black, 0); if (rogue.playbackOmniscience || !player.status[STATUS_HALLUCINATING]) { itemName(theItem, name, true, true, (dim ? &gray : &white)); @@ -4785,17 +4558,17 @@ short printItemInfo(item *theItem, short y, boolean dim, boolean highlight) { describeHallucinatedItem(name); } upperCase(name); - lineCount = wrapText(NULL, name, 20-3); - for (i=initialY + 1; i <= initialY + lineCount + 1 && i < ROWS - 1; i++) { + lineCount = wrapText(NULL, name, 20 - 3); + for (i = initialY + 1; i <= initialY + lineCount + 1 && i < ROWS - 1; i++) { printString(" ", 0, i, (dim ? &darkGray : &gray), &black, 0); } - y = printStringWithWrapping(name, 3, y, 20-3, (dim ? &gray : &white), &black, NULL); // Advances y. + y = printStringWithWrapping(name, 3, y, 20 - 3, (dim ? &gray : &white), &black, NULL); // Advances y. } if (highlight) { - for (i=0; i<20; i++) { - highlightStrength = smoothHiliteGradient(i, 20-1) / 10; - for (j=initialY; j <= y && j < ROWS - 1; j++) { + for (i = 0; i < 20; i++) { + highlightStrength = smoothHiliteGradient(i, 20 - 1) / 10; + for (j = initialY; j <= y && j < ROWS - 1; j++) { highlightScreenCell(i, j, &white, highlightStrength); } } @@ -4812,7 +4585,7 @@ short printTerrainInfo(short x, short y, short py, const char *description, bool color foreColor, backColor; short initialY, i, j, highlightStrength, lineCount; boolean inPath; - char name[DCOLS*2]; + char name[DCOLS * 2]; color textColor; short oldRNG; @@ -4824,7 +4597,7 @@ short printTerrainInfo(short x, short y, short py, const char *description, bool oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; if (py < ROWS - 1) { // Unhighlight if it's highlighted as part of the path. @@ -4840,25 +4613,25 @@ short printTerrainInfo(short x, short y, short py, const char *description, bool applyColorAverage(&foreColor, &black, 50); applyColorAverage(&backColor, &black, 50); } - plotCharWithColor(displayChar, (windowpos){ 0, py }, &foreColor, &backColor); + plotCharWithColor(displayChar, (windowpos){0, py}, &foreColor, &backColor); printString(": ", 1, py, (dim ? &gray : &white), &black, 0); strcpy(name, description); upperCase(name); - lineCount = wrapText(NULL, name, 20-3); - for (i=initialY + 1; i <= initialY + lineCount + 1 && i < ROWS - 1; i++) { + lineCount = wrapText(NULL, name, 20 - 3); + for (i = initialY + 1; i <= initialY + lineCount + 1 && i < ROWS - 1; i++) { printString(" ", 0, i, (dim ? &darkGray : &gray), &black, 0); } textColor = flavorTextColor; if (dim) { applyColorScalar(&textColor, 50); } - py = printStringWithWrapping(name, 3, py, 20-3, &textColor, &black, NULL); // Advances y. + py = printStringWithWrapping(name, 3, py, 20 - 3, &textColor, &black, NULL); // Advances y. } if (highlight) { - for (i=0; i<20; i++) { - highlightStrength = smoothHiliteGradient(i, 20-1) / 10; - for (j=initialY; j <= py && j < ROWS - 1; j++) { + for (i = 0; i < 20; i++) { + highlightStrength = smoothHiliteGradient(i, 20 - 1) / 10; + for (j = initialY; j <= py && j < ROWS - 1; j++) { highlightScreenCell(i, j, &white, highlightStrength); } } @@ -4869,23 +4642,21 @@ short printTerrainInfo(short x, short y, short py, const char *description, bool return py; } -void rectangularShading(short x, short y, short width, short height, - const color *backColor, short opacity, cellDisplayBuffer dbuf[COLS][ROWS]) { +void rectangularShading(short x, short y, short width, short height, const color *backColor, short opacity, cellDisplayBuffer dbuf[COLS][ROWS]) { short i, j, dist; assureCosmeticRNG; - for (i=0; i= x && i < x + width - && j >= y && j < y + height) { + if (i >= x && i < x + width && j >= y && j < y + height) { dbuf[i][j].opacity = min(100, opacity); } else { dist = 0; dist += max(0, max(x - i, i - x - width + 1)); dist += max(0, max(y - j, j - y - height + 1)); - dbuf[i][j].opacity = (int) ((opacity - 10) / max(1, dist)); + dbuf[i][j].opacity = (int)((opacity - 10) / max(1, dist)); if (dbuf[i][j].opacity < 3) { dbuf[i][j].opacity = 0; } @@ -4893,19 +4664,19 @@ void rectangularShading(short x, short y, short width, short height, } } -// for (i=0; i= x && i < x + width && j >= y && j < y + height) { -// plotCharWithColor(' ', (windowpos){ i, j }, &white, &darkGreen); -// } -// } -// } -// displayMoreSign(); + // for (i=0; i= x && i < x + width && j >= y && j < y + height) { + // plotCharWithColor(' ', (windowpos){ i, j }, &white, &darkGreen); + // } + // } + // } + // displayMoreSign(); restoreRNG; } -#define MIN_DEFAULT_INFO_PANEL_WIDTH 33 +#define MIN_DEFAULT_INFO_PANEL_WIDTH 33 // y and width are optional and will be automatically calculated if width <= 0. // Width will automatically be widened if the text would otherwise fall off the bottom of the @@ -4914,10 +4685,7 @@ void rectangularShading(short x, short y, short width, short height, // If buttons are provided, we'll extend the text box downward, re-position the buttons, // run a button input loop and return the result. // (Returns -1 for canceled; otherwise the button index number.) -short printTextBox(char *textBuf, short x, short y, short width, - const color *foreColor, const color *backColor, - cellDisplayBuffer rbuf[COLS][ROWS], - brogueButton *buttons, short buttonCount) { +short printTextBox(char *textBuf, short x, short y, short width, const color *foreColor, const color *backColor, cellDisplayBuffer rbuf[COLS][ROWS], brogueButton *buttons, short buttonCount) { cellDisplayBuffer dbuf[COLS][ROWS]; short x2, y2, lineCount, i, bx, by, padLines; @@ -4942,7 +4710,7 @@ short printTextBox(char *textBuf, short x, short y, short width, x2 = x; } - while (((lineCount = wrapText(NULL, textBuf, width)) + y2) >= ROWS - 2 && width < COLS-5) { + while (((lineCount = wrapText(NULL, textBuf, width)) + y2) >= ROWS - 2 && width < COLS - 5) { // While the text doesn't fit and the width doesn't fill the screen, increase the width. width++; if (x2 + (width / 2) > COLS / 2) { @@ -4956,7 +4724,7 @@ short printTextBox(char *textBuf, short x, short y, short width, padLines = 2; bx = x2 + width; by = y2 + lineCount + 1; - for (i=0; i. */ - #include "Rogue.h" #include "GlobalsBase.h" #include "Globals.h" @@ -35,8 +34,8 @@ item *initializeItem() { short i; item *theItem; - theItem = (item *) malloc(sizeof(item)); - memset(theItem, '\0', sizeof(item) ); + theItem = (item *)malloc(sizeof(item)); + memset(theItem, '\0', sizeof(item)); theItem->category = 0; theItem->kind = 0; @@ -61,7 +60,7 @@ item *initializeItem() { theItem->lastUsed[2] = 0; theItem->nextItem = NULL; - for (i=0; i < KEY_ID_MAXIMUM; i++) { + for (i = 0; i < KEY_ID_MAXIMUM; i++) { theItem->keyLoc[i].x = 0; theItem->keyLoc[i].y = 0; theItem->keyLoc[i].machine = 0; @@ -81,11 +80,11 @@ item *generateItem(unsigned short theCategory, short theKind) { unsigned long pickItemCategory(unsigned long theCategory) { short i, sum, randIndex; - unsigned short correspondingCategories[13] = {GOLD, SCROLL, POTION, STAFF, WAND, WEAPON, ARMOR, FOOD, RING, CHARM, AMULET, GEM, KEY}; + unsigned short correspondingCategories[13] = {GOLD, SCROLL, POTION, STAFF, WAND, WEAPON, ARMOR, FOOD, RING, CHARM, AMULET, GEM, KEY}; sum = 0; - for (i=0; i<13; i++) { + for (i = 0; i < 13; i++) { if (theCategory <= 0 || theCategory & correspondingCategories[i]) { sum += itemGenerationProbabilities[i]; } @@ -97,7 +96,7 @@ unsigned long pickItemCategory(unsigned long theCategory) { randIndex = rand_range(1, sum); - for (i=0; ; i++) { + for (i = 0;; i++) { if (theCategory <= 0 || theCategory & correspondingCategories[i]) { if (randIndex <= itemGenerationProbabilities[i]) { return correspondingCategories[i]; @@ -178,11 +177,7 @@ item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind) { theItem->enchant2 = rand_range(NUMBER_GOOD_WEAPON_ENCHANT_KINDS, NUMBER_WEAPON_RUNIC_KINDS - 1); theItem->flags |= ITEM_RUNIC; } - } else if (rand_range(3, 10) - * ((theItem->flags & ITEM_ATTACKS_STAGGER) ? 2 : 1) - / ((theItem->flags & ITEM_ATTACKS_QUICKLY) ? 2 : 1) - / ((theItem->flags & ITEM_ATTACKS_EXTEND) ? 2 : 1) - > theItem->damage.lowerBound) { + } else if (rand_range(3, 10) * ((theItem->flags & ITEM_ATTACKS_STAGGER) ? 2 : 1) / ((theItem->flags & ITEM_ATTACKS_QUICKLY) ? 2 : 1) / ((theItem->flags & ITEM_ATTACKS_EXTEND) ? 2 : 1) > theItem->damage.lowerBound) { // give it a good runic; lower damage items are more likely to be runic theItem->enchant2 = rand_range(0, NUMBER_GOOD_WEAPON_ENCHANT_KINDS - 1); theItem->flags |= ITEM_RUNIC; @@ -203,7 +198,7 @@ item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind) { } theItem->quiverNumber = rand_range(1, 60000); theItem->flags &= ~(ITEM_CURSED | ITEM_RUNIC); // throwing weapons can't be cursed or runic - theItem->enchant1 = 0; // throwing weapons can't be magical + theItem->enchant1 = 0; // throwing weapons can't be magical } theItem->charges = gameConst->weaponKillsToAutoID; // kill 20 enemies to auto-identify break; @@ -339,9 +334,7 @@ item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind) { message("something has gone terribly wrong!", REQUIRE_ACKNOWLEDGMENT); break; } - if (theItem - && !(theItem->flags & ITEM_IDENTIFIED) - && (!(theItem->category & (POTION | SCROLL) ) || (theEntry && !theEntry->identified))) { + if (theItem && !(theItem->flags & ITEM_IDENTIFIED) && (!(theItem->category & (POTION | SCROLL)) || (theEntry && !theEntry->identified))) { theItem->flags |= ITEM_CAN_BE_IDENTIFIED; } @@ -352,11 +345,11 @@ item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind) { short chooseKind(const itemTable *theTable, short numKinds) { short i, totalFrequencies = 0, randomFrequency; - for (i=0; i theTable[i].frequency; i++) { + for (i = 0; randomFrequency > theTable[i].frequency; i++) { randomFrequency -= max(0, theTable[i].frequency); } return i; @@ -375,15 +368,14 @@ item *placeItem(item *theItem, short x, short y) { theItem->loc.y = y; } - removeItemFromChain(theItem, floorItems); // just in case; double-placing an item will result in game-crashing loops in the item list + removeItemFromChain(theItem, + floorItems); // just in case; double-placing an item will result in game-crashing loops in the item list addItemToChain(theItem, floorItems); pmapAt(theItem->loc)->flags |= HAS_ITEM; if ((theItem->flags & ITEM_MAGIC_DETECTED) && itemMagicPolarity(theItem)) { pmapAt(theItem->loc)->flags |= ITEM_DETECTED; } - if (cellHasTerrainFlag(x, y, T_IS_DF_TRAP) - && !cellHasTerrainFlag(x, y, T_MOVES_ITEMS) - && !(pmap[x][y].flags & PRESSURE_PLATE_DEPRESSED)) { + if (cellHasTerrainFlag(x, y, T_IS_DF_TRAP) && !cellHasTerrainFlag(x, y, T_MOVES_ITEMS) && !(pmap[x][y].flags & PRESSURE_PLATE_DEPRESSED)) { pmap[x][y].flags |= PRESSURE_PLATE_DEPRESSED; if (playerCanSee(x, y)) { @@ -420,10 +412,7 @@ void fillItemSpawnHeatMap(unsigned short heatMap[DCOLS][DROWS], unsigned short h for (dir = 0; dir < 4; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && !cellHasTerrainFlag(newX, newY, T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_AUTO_DESCENT) - && isPassableOrSecretDoor(newX, newY) - && heatLevel < heatMap[newX][newY]) { + if (coordinatesAreInMap(newX, newY) && !cellHasTerrainFlag(newX, newY, T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH | T_AUTO_DESCENT) && isPassableOrSecretDoor(newX, newY) && heatLevel < heatMap[newX][newY]) { fillItemSpawnHeatMap(heatMap, heatLevel, newX, newY); } @@ -444,9 +433,9 @@ void coolHeatMapAt(unsigned short heatMap[DCOLS][DROWS], short x, short y, unsig // lower the heat near the chosen location for (k = -5; k <= 5; k++) { for (l = -5; l <= 5; l++) { - if (coordinatesAreInMap(x+k, y+l) && heatMap[x+k][y+l] == currentHeat) { - heatMap[x+k][y+l] = max(1, heatMap[x+k][y+l]/10); - *totalHeat -= (currentHeat - heatMap[x+k][y+l]); + if (coordinatesAreInMap(x + k, y + l) && heatMap[x + k][y + l] == currentHeat) { + heatMap[x + k][y + l] = max(1, heatMap[x + k][y + l] / 10); + *totalHeat -= (currentHeat - heatMap[x + k][y + l]); } } } @@ -465,10 +454,10 @@ boolean getItemSpawnLoc(unsigned short heatMap[DCOLS][DROWS], short *x, short *y randIndex = rand_range(1, *totalHeat); - //printf("\nrandIndex: %i", randIndex); + // printf("\nrandIndex: %i", randIndex); - for (i=0; iextraItemsPerLevel; numberOfGoldPiles = min(5, rogue.depthLevel * gameConst->depthAccelerator / 4); - for (goldBonusProbability = 60; - rand_percent(goldBonusProbability) && numberOfGoldPiles <= 10; - goldBonusProbability -= 15) { + for (goldBonusProbability = 60; rand_percent(goldBonusProbability) && numberOfGoldPiles <= 10; goldBonusProbability -= 15) { numberOfGoldPiles++; } @@ -564,8 +544,8 @@ void populateItems(short upstairsX, short upstairsY) { // passed to reach the area when pathing to it from the upward staircase. // This is why there are often several items in well hidden secret rooms. Otherwise, // those rooms are usually empty, which is demoralizing after you take the trouble to find them. - for (i=0; i 1) { // Not in walls, hallways, quest rooms, loops or chokepoints, please. itemSpawnHeatMap[i][j] = 0; @@ -590,11 +569,10 @@ void populateItems(short upstairsX, short upstairsY) { // not sure if it's still around, but this is a good-enough failsafe } #ifdef AUDIT_RNG - sprintf(RNGmessage, "%u%s%s\t%s", - itemSpawnHeatMap[i][j], - ((pmap[i][j].flags & IS_CHOKEPOINT) ? " (C)": ""), // chokepoint - ((pmap[i][j].flags & IN_LOOP) ? " (L)": ""), // loop - (i == DCOLS-1 ? "\n" : "")); + sprintf(RNGmessage, "%u%s%s\t%s", itemSpawnHeatMap[i][j], + ((pmap[i][j].flags & IS_CHOKEPOINT) ? " (C)" : ""), // chokepoint + ((pmap[i][j].flags & IN_LOOP) ? " (L)" : ""), // loop + (i == DCOLS - 1 ? "\n" : "")); RNGLog(RNGmessage); #endif totalHeat += itemSpawnHeatMap[i][j]; @@ -603,8 +581,8 @@ void populateItems(short upstairsX, short upstairsY) { if (D_INSPECT_LEVELGEN) { short **map = allocGrid(); - for (i=0; i gameConst->amuletLevel) { theCategory = GEM; } else { - + for (j = 0; j < gameConst->numberMeteredItems; j++) { // Create any metered items that reach generation thresholds - if (meteredItemsGenerationTable[j].levelScaling != 0 && - rogue.meteredItems[j].numberSpawned * meteredItemsGenerationTable[j].genMultiplier + meteredItemsGenerationTable[j].genIncrement < - rogue.depthLevel * meteredItemsGenerationTable[j].levelScaling + randomDepthOffset) { - theCategory = meteredItemsGenerationTable[j].category; - theKind = meteredItemsGenerationTable[j].kind; - break; + if (meteredItemsGenerationTable[j].levelScaling != 0 + && rogue.meteredItems[j].numberSpawned * meteredItemsGenerationTable[j].genMultiplier + meteredItemsGenerationTable[j].genIncrement < rogue.depthLevel * meteredItemsGenerationTable[j].levelScaling + randomDepthOffset) { + theCategory = meteredItemsGenerationTable[j].category; + theKind = meteredItemsGenerationTable[j].kind; + break; } // Create any metered items that reach hard by-level guarantees - if (rogue.depthLevel == meteredItemsGenerationTable[j].levelGuarantee && - rogue.meteredItems[j].numberSpawned < meteredItemsGenerationTable[j].itemNumberGuarantee) { - theCategory = meteredItemsGenerationTable[j].category; - theKind = meteredItemsGenerationTable[j].kind; - break; - } + if (rogue.depthLevel == meteredItemsGenerationTable[j].levelGuarantee && rogue.meteredItems[j].numberSpawned < meteredItemsGenerationTable[j].itemNumberGuarantee) { + theCategory = meteredItemsGenerationTable[j].category; + theKind = meteredItemsGenerationTable[j].kind; + break; + } } } @@ -680,7 +655,7 @@ void populateItems(short upstairsX, short upstairsY) { if ((theItem->category & FOOD) || ((theItem->category & POTION) && theItem->kind == POTION_STRENGTH)) { do { randomMatchingLocation(&x, &y, FLOOR, NOTHING, -1); // Food and gain strength don't follow the heat map. - } while (passableArcCount(x, y) > 1); // Not in a hallway. + } while (passableArcCount(x, y) > 1); // Not in a hallway. } else { getItemSpawnLoc(itemSpawnHeatMap, &x, &y, &totalHeat); } @@ -708,21 +683,21 @@ void populateItems(short upstairsX, short upstairsY) { if (D_INSPECT_LEVELGEN) { short **map = allocGrid(); short i2, j2; - for (i2=0; i2displayChar, mapToWindow((pos){ x, y }), &black, &purple); + plotCharWithColor(theItem->displayChar, mapToWindow((pos){x, y}), &black, &purple); temporaryMessage("Added an item.", REQUIRE_ACKNOWLEDGMENT); } } // Now generate gold. - for (i=0; icategory & GEM) { - for (tempItem = packItems->nextItem; - tempItem != NULL && !((tempItem->category & GEM) && theItem->originDepth == tempItem->originDepth); - tempItem = tempItem->nextItem); + for (tempItem = packItems->nextItem; tempItem != NULL && !((tempItem->category & GEM) && theItem->originDepth == tempItem->originDepth); tempItem = tempItem->nextItem) + ; return (tempItem ? true : false); } else if (!(theItem->quiverNumber)) { return false; } else { - for (tempItem = packItems->nextItem; - tempItem != NULL && tempItem->quiverNumber != theItem->quiverNumber; - tempItem = tempItem->nextItem); + for (tempItem = packItems->nextItem; tempItem != NULL && tempItem->quiverNumber != theItem->quiverNumber; tempItem = tempItem->nextItem) + ; return (tempItem ? true : false); } } @@ -800,16 +773,12 @@ void pickUpItemAt(short x, short y) { return; } - if ((theItem->flags & ITEM_KIND_AUTO_ID) - && tableForItemCategory(theItem->category) - && !(tableForItemCategory(theItem->category)[theItem->kind].identified)) { + if ((theItem->flags & ITEM_KIND_AUTO_ID) && tableForItemCategory(theItem->category) && !(tableForItemCategory(theItem->category)[theItem->kind].identified)) { identifyItemKind(theItem); } - if ((theItem->category & WAND) - && wandTable[theItem->kind].identified - && wandTable[theItem->kind].range.lowerBound == wandTable[theItem->kind].range.upperBound) { + if ((theItem->category & WAND) && wandTable[theItem->kind].identified && wandTable[theItem->kind].range.lowerBound == wandTable[theItem->kind].range.upperBound) { theItem->flags |= ITEM_IDENTIFIED; } @@ -847,8 +816,7 @@ void pickUpItemAt(short x, short y) { removeItemFrom(x, y); // triggers tiles with T_PROMOTES_ON_ITEM_PICKUP - if ((theItem->category & AMULET) - && !(rogue.yendorWarden)) { + if ((theItem->category & AMULET) && !(rogue.yendorWarden)) { // Identify the amulet guardian, or generate one if there isn't one. for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); @@ -867,7 +835,7 @@ void pickUpItemAt(short x, short y) { } } } else { - theItem->flags |= ITEM_PLAYER_AVOIDS; // explore shouldn't try to pick it up more than once. + theItem->flags |= ITEM_PLAYER_AVOIDS; // explore shouldn't try to pick it up more than once. itemName(theItem, buf2, false, true, NULL); // include article sprintf(buf, "Your pack is too full to pick up %s.", buf2); message(buf, 0); @@ -877,8 +845,7 @@ void pickUpItemAt(short x, short y) { void conflateItemCharacteristics(item *newItem, item *oldItem) { // let magic detection and other flags propagate to the new stack... - newItem->flags |= (oldItem->flags & (ITEM_MAGIC_DETECTED | ITEM_IDENTIFIED | ITEM_PROTECTED | ITEM_RUNIC - | ITEM_RUNIC_HINTED | ITEM_CAN_BE_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN)); + newItem->flags |= (oldItem->flags & (ITEM_MAGIC_DETECTED | ITEM_IDENTIFIED | ITEM_PROTECTED | ITEM_RUNIC | ITEM_RUNIC_HINTED | ITEM_CAN_BE_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN)); // keep the higher enchantment and lower strength requirement... if (oldItem->enchant1 > newItem->enchant1) { @@ -894,7 +861,7 @@ void conflateItemCharacteristics(item *newItem, item *oldItem) { } void stackItems(item *newItem, item *oldItem) { - //Increment the quantity of the old item... + // Increment the quantity of the old item... newItem->quantity += oldItem->quantity; // ...conflate attributes... @@ -906,8 +873,7 @@ void stackItems(item *newItem, item *oldItem) { boolean inventoryLetterAvailable(char proposedLetter) { item *theItem; - if (proposedLetter >= 'a' - && proposedLetter <= 'z') { + if (proposedLetter >= 'a' && proposedLetter <= 'z') { for (theItem = packItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { if (theItem->inventoryLetter == proposedLetter) { @@ -924,11 +890,9 @@ item *addItemToPack(item *theItem) { char itemLetter; // Can the item stack with another in the inventory? - if (theItem->category & (FOOD|POTION|SCROLL|GEM)) { + if (theItem->category & (FOOD | POTION | SCROLL | GEM)) { for (tempItem = packItems->nextItem; tempItem != NULL; tempItem = tempItem->nextItem) { - if (theItem->category == tempItem->category - && theItem->kind == tempItem->kind - && (!(theItem->category & GEM) || theItem->originDepth == tempItem->originDepth)) { + if (theItem->category == tempItem->category && theItem->kind == tempItem->kind && (!(theItem->category & GEM) || theItem->originDepth == tempItem->originDepth)) { // We found a match! stackItems(tempItem, theItem); @@ -939,8 +903,7 @@ item *addItemToPack(item *theItem) { } } else if (theItem->category & WEAPON && theItem->quiverNumber > 0) { for (tempItem = packItems->nextItem; tempItem != NULL; tempItem = tempItem->nextItem) { - if (theItem->category == tempItem->category && theItem->kind == tempItem->kind - && theItem->quiverNumber == tempItem->quiverNumber) { + if (theItem->category == tempItem->category && theItem->kind == tempItem->kind && theItem->quiverNumber == tempItem->quiverNumber) { // We found a match! stackItems(tempItem, theItem); @@ -959,9 +922,8 @@ item *addItemToPack(item *theItem) { } // insert at proper place in pack chain - for (previousItem = packItems; - previousItem->nextItem != NULL && previousItem->nextItem->category <= theItem->category; - previousItem = previousItem->nextItem); + for (previousItem = packItems; previousItem->nextItem != NULL && previousItem->nextItem->category <= theItem->category; previousItem = previousItem->nextItem) + ; theItem->nextItem = previousItem->nextItem; previousItem->nextItem = theItem; @@ -971,7 +933,7 @@ item *addItemToPack(item *theItem) { short numberOfItemsInPack() { short theCount = 0; item *theItem; - for(theItem = packItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { + for (theItem = packItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { theCount += (theItem->category & (WEAPON | GEM) ? 1 : theItem->quantity); } return theCount; @@ -982,7 +944,7 @@ char nextAvailableInventoryCharacter() { short i; item *theItem; char c; - for(i=0; i<26; i++) { + for (i = 0; i < 26; i++) { charTaken[i] = false; } for (theItem = packItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { @@ -991,7 +953,7 @@ char nextAvailableInventoryCharacter() { charTaken[c - 'a'] = true; } } - for(i=0; i<26; i++) { + for (i = 0; i < 26; i++) { if (!charTaken[i]) { return ('a' + i); } @@ -1002,8 +964,7 @@ char nextAvailableInventoryCharacter() { void checkForDisenchantment(item *theItem) { char buf[COLS], buf2[COLS]; - if ((theItem->flags & ITEM_RUNIC) - && (((theItem->category & WEAPON) && theItem->enchant2 < NUMBER_GOOD_WEAPON_ENCHANT_KINDS) || ((theItem->category & ARMOR) && theItem->enchant2 < NUMBER_GOOD_ARMOR_ENCHANT_KINDS)) + if ((theItem->flags & ITEM_RUNIC) && (((theItem->category & WEAPON) && theItem->enchant2 < NUMBER_GOOD_WEAPON_ENCHANT_KINDS) || ((theItem->category & ARMOR) && theItem->enchant2 < NUMBER_GOOD_ARMOR_ENCHANT_KINDS)) && theItem->enchant1 <= 0) { theItem->enchant2 = 0; @@ -1016,16 +977,14 @@ void checkForDisenchantment(item *theItem) { messageWithColor(buf, &itemMessageColor, 0); } } - if (theItem->flags & ITEM_CURSED - && theItem->enchant1 >= 0) { + if (theItem->flags & ITEM_CURSED && theItem->enchant1 >= 0) { theItem->flags &= ~ITEM_CURSED; } } boolean itemIsSwappable(const item *theItem) { - if ((theItem->category & CAN_BE_SWAPPED) - && theItem->quiverNumber == 0) { + if ((theItem->category & CAN_BE_SWAPPED) && theItem->quiverNumber == 0) { return true; } else { @@ -1037,14 +996,10 @@ void swapItemToEnchantLevel(item *theItem, short newEnchant, boolean enchantment short x, y, charmPercent; char buf1[COLS * 3], buf2[COLS * 3]; - if ((theItem->category & STAFF) && newEnchant < 2 - || (theItem->category & CHARM) && newEnchant < 1 - || (theItem->category & WAND) && newEnchant < 0) { + if ((theItem->category & STAFF) && newEnchant < 2 || (theItem->category & CHARM) && newEnchant < 1 || (theItem->category & WAND) && newEnchant < 0) { itemName(theItem, buf1, false, true, NULL); - sprintf(buf2, "%s shatter%s from the strain!", - buf1, - theItem->quantity == 1 ? "s" : ""); + sprintf(buf2, "%s shatter%s from the strain!", buf1, theItem->quantity == 1 ? "s" : ""); x = theItem->loc.x; y = theItem->loc.y; removeItemFromChain(theItem, floorItems); @@ -1056,8 +1011,7 @@ void swapItemToEnchantLevel(item *theItem, short newEnchant, boolean enchantment messageWithColor(buf2, &itemMessageColor, 0); } } else { - if ((theItem->category & STAFF) - && theItem->charges > newEnchant) { + if ((theItem->category & STAFF) && theItem->charges > newEnchant) { theItem->charges = newEnchant; } @@ -1091,8 +1045,7 @@ void swapItemToEnchantLevel(item *theItem, short newEnchant, boolean enchantment } boolean enchantLevelKnown(const item *theItem) { - if ((theItem->category & STAFF) - && (theItem->flags & ITEM_MAX_CHARGES_KNOWN)) { + if ((theItem->category & STAFF) && (theItem->flags & ITEM_MAX_CHARGES_KNOWN)) { return true; } else { @@ -1117,10 +1070,7 @@ boolean swapItemEnchants(const short machineNumber) { for (i = 0; i < DCOLS; i++) { for (j = 0; j < DROWS; j++) { tempItem = itemAtLoc(i, j); - if (tempItem - && pmap[i][j].machineNumber == machineNumber - && cellHasTMFlag(i, j, TM_SWAP_ENCHANTS_ACTIVATION) - && itemIsSwappable(tempItem)) { + if (tempItem && pmap[i][j].machineNumber == machineNumber && cellHasTMFlag(i, j, TM_SWAP_ENCHANTS_ACTIVATION) && itemIsSwappable(tempItem)) { if (lockedItem) { if (effectiveEnchantLevel(lockedItem) != effectiveEnchantLevel(tempItem)) { @@ -1142,11 +1092,11 @@ boolean swapItemEnchants(const short machineNumber) { void updateFloorItems() { short x, y; - char buf[DCOLS*3], buf2[DCOLS*3]; + char buf[DCOLS * 3], buf2[DCOLS * 3]; enum dungeonLayers layer; item *theItem, *nextItem; - for (theItem=floorItems->nextItem; theItem != NULL; theItem = nextItem) { + for (theItem = floorItems->nextItem; theItem != NULL; theItem = nextItem) { nextItem = theItem->nextItem; x = theItem->loc.x; y = theItem->loc.y; @@ -1176,14 +1126,13 @@ void updateFloorItems() { } else { // Add to next level's chain. theItem->spawnTurnNumber = rogue.absoluteTurnNumber; - theItem->nextItem = levels[rogue.depthLevel-1 + 1].items; - levels[rogue.depthLevel-1 + 1].items = theItem; + theItem->nextItem = levels[rogue.depthLevel - 1 + 1].items; + levels[rogue.depthLevel - 1 + 1].items = theItem; } refreshDungeonCell(x, y); continue; } - if ((cellHasTerrainFlag(x, y, T_IS_FIRE) && (theItem->flags & ITEM_FLAMMABLE)) - || (cellHasTerrainFlag(x, y, T_LAVA_INSTA_DEATH) && !(theItem->category & AMULET))) { + if ((cellHasTerrainFlag(x, y, T_IS_FIRE) && (theItem->flags & ITEM_FLAMMABLE)) || (cellHasTerrainFlag(x, y, T_LAVA_INSTA_DEATH) && !(theItem->category & AMULET))) { burnItem(theItem); continue; @@ -1210,26 +1159,20 @@ void updateFloorItems() { } continue; } - if (pmap[x][y].machineNumber - && pmap[x][y].machineNumber == pmapAt(player.loc)->machineNumber - && (theItem->flags & ITEM_KIND_AUTO_ID)) { + if (pmap[x][y].machineNumber && pmap[x][y].machineNumber == pmapAt(player.loc)->machineNumber && (theItem->flags & ITEM_KIND_AUTO_ID)) { identifyItemKind(theItem); } - if (cellHasTMFlag(x, y, TM_SWAP_ENCHANTS_ACTIVATION) - && pmap[x][y].machineNumber) { + if (cellHasTMFlag(x, y, TM_SWAP_ENCHANTS_ACTIVATION) && pmap[x][y].machineNumber) { - while (nextItem != NULL - && pmap[x][y].machineNumber == pmapAt(nextItem->loc)->machineNumber - && cellHasTMFlag(nextItem->loc.x, nextItem->loc.y, TM_SWAP_ENCHANTS_ACTIVATION)) { + while (nextItem != NULL && pmap[x][y].machineNumber == pmapAt(nextItem->loc)->machineNumber && cellHasTMFlag(nextItem->loc.x, nextItem->loc.y, TM_SWAP_ENCHANTS_ACTIVATION)) { // Skip future items that are also swappable, so that we don't inadvertently // destroy the next item and then try to update it. nextItem = nextItem->nextItem; } - if (!circuitBreakersPreventActivation(pmap[x][y].machineNumber) - && swapItemEnchants(pmap[x][y].machineNumber)) { + if (!circuitBreakersPreventActivation(pmap[x][y].machineNumber) && swapItemEnchants(pmap[x][y].machineNumber)) { activateMachine(pmap[x][y].machineNumber); } @@ -1260,10 +1203,9 @@ boolean inscribeItem(item *theItem) { } boolean itemCanBeCalled(item *theItem) { - if (theItem->category & (WEAPON|ARMOR|SCROLL|RING|POTION|STAFF|WAND|CHARM)) { + if (theItem->category & (WEAPON | ARMOR | SCROLL | RING | POTION | STAFF | WAND | CHARM)) { return true; - } else if ((theItem->category & (POTION | SCROLL)) - && !tableForItemCategory(theItem->category)[theItem->kind].identified) { + } else if ((theItem->category & (POTION | SCROLL)) && !tableForItemCategory(theItem->category)[theItem->kind].identified) { return true; } else { return false; @@ -1283,17 +1225,14 @@ void call(item *theItem) { // Hijack the "item can be identified" flag for this purpose, // and then reset it immediately afterward. for (tempItem = packItems->nextItem; tempItem != NULL; tempItem = tempItem->nextItem) { - if ((tempItem->category & (POTION | SCROLL)) - && tableForItemCategory(tempItem->category)[tempItem->kind].identified) { + if ((tempItem->category & (POTION | SCROLL)) && tableForItemCategory(tempItem->category)[tempItem->kind].identified) { tempItem->flags &= ~ITEM_CAN_BE_IDENTIFIED; } else { tempItem->flags |= ITEM_CAN_BE_IDENTIFIED; } } - theItem = promptForItemOfType((WEAPON|ARMOR|SCROLL|RING|POTION|STAFF|WAND|CHARM), ITEM_CAN_BE_IDENTIFIED, 0, - KEYBOARD_LABELS ? "Call what? (a-z, shift for more info; or to cancel)" : "Call what?", - true); + theItem = promptForItemOfType((WEAPON | ARMOR | SCROLL | RING | POTION | STAFF | WAND | CHARM), ITEM_CAN_BE_IDENTIFIED, 0, KEYBOARD_LABELS ? "Call what? (a-z, shift for more info; or to cancel)" : "Call what?", true); updateIdentifiableItems(); // Reset the flags. } if (theItem == NULL) { @@ -1304,11 +1243,11 @@ void call(item *theItem) { confirmMessages(); - if ((theItem->flags & ITEM_IDENTIFIED) || theItem->category & (WEAPON|ARMOR|CHARM|FOOD|GOLD|AMULET|GEM)) { + if ((theItem->flags & ITEM_IDENTIFIED) || theItem->category & (WEAPON | ARMOR | CHARM | FOOD | GOLD | AMULET | GEM)) { if (theItem->category & (WEAPON | ARMOR | CHARM | STAFF | WAND | RING)) { if (inscribeItem(theItem)) { command[c++] = '\0'; - strcat((char *) command, theItem->inscription); + strcat((char *)command, theItem->inscription); recordKeystrokeSequence(command); recordKeystroke(RETURN_KEY, false, false); } @@ -1322,7 +1261,7 @@ void call(item *theItem) { if (tableForItemCategory(theItem->category)[theItem->kind].identified) { if (inscribeItem(theItem)) { command[c++] = '\0'; - strcat((char *) command, theItem->inscription); + strcat((char *)command, theItem->inscription); recordKeystrokeSequence(command); recordKeystroke(RETURN_KEY, false, false); } @@ -1331,7 +1270,7 @@ void call(item *theItem) { command[c++] = 'y'; // y means yes, since the recording also needs to negotiate the above confirmation prompt. if (inscribeItem(theItem)) { command[c++] = '\0'; - strcat((char *) command, theItem->inscription); + strcat((char *)command, theItem->inscription); recordKeystrokeSequence(command); recordKeystroke(RETURN_KEY, false, false); } @@ -1341,12 +1280,11 @@ void call(item *theItem) { } } - if (tableForItemCategory(theItem->category) - && !(tableForItemCategory(theItem->category)[theItem->kind].identified)) { + if (tableForItemCategory(theItem->category) && !(tableForItemCategory(theItem->category)[theItem->kind].identified)) { if (getInputTextString(itemText, "call them: \"", 29, "", "\"", TEXT_INPUT_NORMAL, false)) { command[c++] = '\0'; - strcat((char *) command, itemText); + strcat((char *)command, itemText); recordKeystrokeSequence(command); recordKeystroke(RETURN_KEY, false, false); if (itemText[0]) { @@ -1369,11 +1307,10 @@ void call(item *theItem) { // IncludeDetails governs things such as enchantment, charges, strength requirement, times used, etc. // IncludeArticle governs the article -- e.g. "some" food, "5" darts, "a" pink potion. // If baseColor is provided, then the suffix will be in gray, flavor portions of the item name (e.g. a "pink" potion, -// a "sandalwood" staff, a "ruby" ring) will be in dark purple, and the Amulet of Yendor and lumenstones will be in yellow. -// BaseColor itself will be the color that the name reverts to outside of these colored portions. +// a "sandalwood" staff, a "ruby" ring) will be in dark purple, and the Amulet of Yendor and lumenstones will be in +// yellow. BaseColor itself will be the color that the name reverts to outside of these colored portions. void itemName(item *theItem, char *root, boolean includeDetails, boolean includeArticle, const color *baseColor) { - char buf[DCOLS * 5], pluralization[10], article[10] = "", runicName[30], - grayEscapeSequence[5], purpleEscapeSequence[5], yellowEscapeSequence[5], baseEscapeSequence[5]; + char buf[DCOLS * 5], pluralization[10], article[10] = "", runicName[30], grayEscapeSequence[5], purpleEscapeSequence[5], yellowEscapeSequence[5], baseEscapeSequence[5]; color tempColor; strcpy(pluralization, (theItem->quantity > 1 ? "s" : "")); @@ -1388,7 +1325,7 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include encodeMessageColor(purpleEscapeSequence, 0, &tempColor); tempColor = gray; - //applyColorMultiplier(&tempColor, baseColor); + // applyColorMultiplier(&tempColor, baseColor); encodeMessageColor(grayEscapeSequence, 0, &tempColor); tempColor = itemMessageColor; @@ -1398,9 +1335,9 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include encodeMessageColor(baseEscapeSequence, 0, baseColor); } - switch (theItem -> category) { + switch (theItem->category) { case FOOD: - if (theItem -> kind == FRUIT) { + if (theItem->kind == FRUIT) { sprintf(root, "mango%s", pluralization); } else { if (theItem->quantity == 1) { @@ -1439,32 +1376,21 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include sprintf(root, "%s", armorTable[theItem->kind].name); if (includeDetails) { - if ((theItem->flags & ITEM_RUNIC) - && ((theItem->flags & ITEM_RUNIC_IDENTIFIED) - || rogue.playbackOmniscience)) { + if ((theItem->flags & ITEM_RUNIC) && ((theItem->flags & ITEM_RUNIC_IDENTIFIED) || rogue.playbackOmniscience)) { itemRunicName(theItem, runicName); sprintf(buf, "%s of %s%s", root, runicName, grayEscapeSequence); strcpy(root, buf); - } + } if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { - sprintf(buf, "%s%i %s%s [%i]<%i>", - (theItem->enchant1 < 0 ? "" : "+"), - theItem->enchant1, - root, - grayEscapeSequence, - theItem->armor/10 + theItem->enchant1, - theItem->strengthRequired); + sprintf(buf, "%s%i %s%s [%i]<%i>", (theItem->enchant1 < 0 ? "" : "+"), theItem->enchant1, root, grayEscapeSequence, theItem->armor / 10 + theItem->enchant1, theItem->strengthRequired); strcpy(root, buf); } else { sprintf(buf, "%s%s <%i>", root, grayEscapeSequence, theItem->strengthRequired); strcpy(root, buf); } - if ((theItem->flags & ITEM_RUNIC) - && (theItem->flags & (ITEM_IDENTIFIED | ITEM_RUNIC_HINTED)) - && !(theItem->flags & ITEM_RUNIC_IDENTIFIED) - && !rogue.playbackOmniscience) { + if ((theItem->flags & ITEM_RUNIC) && (theItem->flags & (ITEM_IDENTIFIED | ITEM_RUNIC_HINTED)) && !(theItem->flags & ITEM_RUNIC_IDENTIFIED) && !rogue.playbackOmniscience) { strcat(root, " (unknown runic)"); } } @@ -1473,72 +1399,37 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include if (scrollTable[theItem->kind].identified || rogue.playbackOmniscience) { sprintf(root, "scroll%s of %s", pluralization, scrollTable[theItem->kind].name); } else if (scrollTable[theItem->kind].called) { - sprintf(root, "scroll%s called %s%s%s", - pluralization, - purpleEscapeSequence, - scrollTable[theItem->kind].callTitle, - baseEscapeSequence); + sprintf(root, "scroll%s called %s%s%s", pluralization, purpleEscapeSequence, scrollTable[theItem->kind].callTitle, baseEscapeSequence); } else { - sprintf(root, "scroll%s entitled %s\"%s\"%s", - pluralization, - purpleEscapeSequence, - scrollTable[theItem->kind].flavor, - baseEscapeSequence); + sprintf(root, "scroll%s entitled %s\"%s\"%s", pluralization, purpleEscapeSequence, scrollTable[theItem->kind].flavor, baseEscapeSequence); } break; case POTION: if (potionTable[theItem->kind].identified || rogue.playbackOmniscience) { sprintf(root, "potion%s of %s", pluralization, potionTable[theItem->kind].name); } else if (potionTable[theItem->kind].called) { - sprintf(root, "potion%s called %s%s%s", - pluralization, - purpleEscapeSequence, - potionTable[theItem->kind].callTitle, - baseEscapeSequence); + sprintf(root, "potion%s called %s%s%s", pluralization, purpleEscapeSequence, potionTable[theItem->kind].callTitle, baseEscapeSequence); } else { - sprintf(root, "%s%s%s potion%s", - purpleEscapeSequence, - potionTable[theItem->kind].flavor, - baseEscapeSequence, - pluralization); + sprintf(root, "%s%s%s potion%s", purpleEscapeSequence, potionTable[theItem->kind].flavor, baseEscapeSequence, pluralization); } break; case WAND: if (wandTable[theItem->kind].identified || rogue.playbackOmniscience) { - sprintf(root, "wand%s of %s", - pluralization, - wandTable[theItem->kind].name); + sprintf(root, "wand%s of %s", pluralization, wandTable[theItem->kind].name); } else if (wandTable[theItem->kind].called) { - sprintf(root, "wand%s called %s%s%s", - pluralization, - purpleEscapeSequence, - wandTable[theItem->kind].callTitle, - baseEscapeSequence); + sprintf(root, "wand%s called %s%s%s", pluralization, purpleEscapeSequence, wandTable[theItem->kind].callTitle, baseEscapeSequence); } else { - sprintf(root, "%s%s%s wand%s", - purpleEscapeSequence, - wandTable[theItem->kind].flavor, - baseEscapeSequence, - pluralization); + sprintf(root, "%s%s%s wand%s", purpleEscapeSequence, wandTable[theItem->kind].flavor, baseEscapeSequence, pluralization); } if (includeDetails) { if (theItem->flags & (ITEM_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN) || rogue.playbackOmniscience) { - sprintf(buf, "%s%s [%i]", - root, - grayEscapeSequence, - theItem->charges); + sprintf(buf, "%s%s [%i]", root, grayEscapeSequence, theItem->charges); strcpy(root, buf); } else if (theItem->enchant2 > 2) { - sprintf(buf, "%s%s (used %i times)", - root, - grayEscapeSequence, - theItem->enchant2); + sprintf(buf, "%s%s (used %i times)", root, grayEscapeSequence, theItem->enchant2); strcpy(root, buf); } else if (theItem->enchant2) { - sprintf(buf, "%s%s (used %s)", - root, - grayEscapeSequence, - (theItem->enchant2 == 2 ? "twice" : "once")); + sprintf(buf, "%s%s (used %s)", root, grayEscapeSequence, (theItem->enchant2 == 2 ? "twice" : "once")); strcpy(root, buf); } } @@ -1547,17 +1438,9 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include if (staffTable[theItem->kind].identified || rogue.playbackOmniscience) { sprintf(root, "staff%s of %s", pluralization, staffTable[theItem->kind].name); } else if (staffTable[theItem->kind].called) { - sprintf(root, "staff%s called %s%s%s", - pluralization, - purpleEscapeSequence, - staffTable[theItem->kind].callTitle, - baseEscapeSequence); + sprintf(root, "staff%s called %s%s%s", pluralization, purpleEscapeSequence, staffTable[theItem->kind].callTitle, baseEscapeSequence); } else { - sprintf(root, "%s%s%s staff%s", - purpleEscapeSequence, - staffTable[theItem->kind].flavor, - baseEscapeSequence, - pluralization); + sprintf(root, "%s%s%s staff%s", purpleEscapeSequence, staffTable[theItem->kind].flavor, baseEscapeSequence, pluralization); } if (includeDetails) { if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { @@ -1573,17 +1456,9 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include if (ringTable[theItem->kind].identified || rogue.playbackOmniscience) { sprintf(root, "ring%s of %s", pluralization, ringTable[theItem->kind].name); } else if (ringTable[theItem->kind].called) { - sprintf(root, "ring%s called %s%s%s", - pluralization, - purpleEscapeSequence, - ringTable[theItem->kind].callTitle, - baseEscapeSequence); + sprintf(root, "ring%s called %s%s%s", pluralization, purpleEscapeSequence, ringTable[theItem->kind].callTitle, baseEscapeSequence); } else { - sprintf(root, "%s%s%s ring%s", - purpleEscapeSequence, - ringTable[theItem->kind].flavor, - baseEscapeSequence, - pluralization); + sprintf(root, "%s%s%s ring%s", purpleEscapeSequence, ringTable[theItem->kind].flavor, baseEscapeSequence, pluralization); } if (includeDetails && ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience)) { sprintf(buf, "%s%i %s", (theItem->enchant1 < 0 ? "" : "+"), theItem->enchant1, root); @@ -1598,10 +1473,7 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include strcpy(root, buf); if (theItem->charges) { - sprintf(buf, "%s %s(%i%%)", - root, - grayEscapeSequence, - (charmRechargeDelay(theItem->kind, theItem->enchant1) - theItem->charges) * 100 / charmRechargeDelay(theItem->kind, theItem->enchant1)); + sprintf(buf, "%s %s(%i%%)", root, grayEscapeSequence, (charmRechargeDelay(theItem->kind, theItem->enchant1) - theItem->charges) * 100 / charmRechargeDelay(theItem->kind, theItem->enchant1)); strcpy(root, buf); } else { strcat(root, grayEscapeSequence); @@ -1620,16 +1492,9 @@ void itemName(item *theItem, char *root, boolean includeDetails, boolean include break; case KEY: if (includeDetails && theItem->originDepth > 0 && theItem->originDepth != rogue.depthLevel) { - sprintf(root, "%s%s%s from depth %i", - keyTable[theItem->kind].name, - pluralization, - grayEscapeSequence, - theItem->originDepth); + sprintf(root, "%s%s%s from depth %i", keyTable[theItem->kind].name, pluralization, grayEscapeSequence, theItem->originDepth); } else { - sprintf(root, - keyTable[theItem->kind].name, - "%s%s", - pluralization); + sprintf(root, keyTable[theItem->kind].name, "%s%s", pluralization); } break; default: @@ -1670,7 +1535,7 @@ void itemKindName(item *theItem, char *kindName) { } else { switch (theItem->category) { case KEY: - strcpy(kindName, keyTable[theItem->kind].name); //keys are not randomly generated but have a lookup table + strcpy(kindName, keyTable[theItem->kind].name); // keys are not randomly generated but have a lookup table break; // these items have only one kind per category and no lookup table case GOLD: @@ -1690,11 +1555,10 @@ void itemKindName(item *theItem, char *kindName) { } void itemRunicName(item *theItem, char *runicName) { - char vorpalEnemyMonsterClass[15] =""; + char vorpalEnemyMonsterClass[15] = ""; if (theItem->flags & ITEM_RUNIC) { - if ((theItem->category == ARMOR && theItem->enchant2 == A_IMMUNITY) - || (theItem->category == WEAPON && theItem->enchant2 == W_SLAYING)) { + if ((theItem->category == ARMOR && theItem->enchant2 == A_IMMUNITY) || (theItem->category == WEAPON && theItem->enchant2 == W_SLAYING)) { sprintf(vorpalEnemyMonsterClass, "%s ", monsterClassCatalog[theItem->vorpalEnemy].name); } if (theItem->category == WEAPON) { @@ -1705,9 +1569,7 @@ void itemRunicName(item *theItem, char *runicName) { } } -static int enchantMagnitude() { - return tableForItemCategory(SCROLL)[SCROLL_ENCHANTING].power; -} +static int enchantMagnitude() { return tableForItemCategory(SCROLL)[SCROLL_ENCHANTING].power; } itemTable *tableForItemCategory(enum itemCategory theCat) { switch (theCat) { @@ -1746,16 +1608,13 @@ boolean isVowelish(char *theChar) { for (i = 0; i < 29; i++) { upperCase(&(str[i])); } - if (stringsMatch(str, "UNI") // Words that start with "uni" aren't treated like vowels; e.g., "a" unicorn. - || stringsMatch(str, "EU")) { // Words that start with "eu" aren't treated like vowels; e.g., "a" eucalpytus staff. + if (stringsMatch(str, "UNI") // Words that start with "uni" aren't treated like vowels; e.g., "a" unicorn. + || stringsMatch(str, + "EU")) { // Words that start with "eu" aren't treated like vowels; e.g., "a" eucalpytus staff. return false; } else { - return (str[0] == 'A' - || str[0] == 'E' - || str[0] == 'I' - || str[0] == 'O' - || str[0] == 'U'); + return (str[0] == 'A' || str[0] == 'E' || str[0] == 'I' || str[0] == 'O' || str[0] == 'U'); } } @@ -1788,8 +1647,7 @@ short effectiveRingEnchant(item *theItem) { if (theItem->category != RING) { return 0; } - if (!(theItem->flags & ITEM_IDENTIFIED) - && theItem->enchant1 > 0) { + if (!(theItem->flags & ITEM_IDENTIFIED) && theItem->enchant1 > 0) { return theItem->timesEnchanted + 1; // Unidentified positive rings act as +1 until identified. } @@ -1819,18 +1677,16 @@ void itemDetails(char *buf, item *theItem) { fixpt currentDamage, newDamage; short nextLevelState = 0, new, current, accuracyChange, damageChange; unsigned long turnsSinceLatestUse; - const char weaponRunicEffectDescriptions[NUMBER_WEAPON_RUNIC_KINDS][DCOLS] = { - "time will stop while you take an extra turn", - "the enemy will die instantly", - "the enemy will be paralyzed", - "[multiplicity]", // never used - "the enemy will be slowed", - "the enemy will be confused", - "the enemy will be flung", - "[slaying]", // never used - "the enemy will be healed", - "the enemy will be cloned" - }; + const char weaponRunicEffectDescriptions[NUMBER_WEAPON_RUNIC_KINDS][DCOLS] = {"time will stop while you take an extra turn", + "the enemy will die instantly", + "the enemy will be paralyzed", + "[multiplicity]", // never used + "the enemy will be slowed", + "the enemy will be confused", + "the enemy will be flung", + "[slaying]", // never used + "the enemy will be healed", + "the enemy will be cloned"}; goodColorEscape[0] = badColorEscape[0] = whiteColorEscape[0] = '\0'; encodeMessageColor(goodColorEscape, 0, &goodMessageColor); @@ -1858,58 +1714,50 @@ void itemDetails(char *buf, item *theItem) { itemName(theItem, theName, false, false, NULL); // introductory text - if (tableForItemCategory(theItem->category) - && (tableForItemCategory(theItem->category)[theItem->kind].identified || rogue.playbackOmniscience)) { + if (tableForItemCategory(theItem->category) && (tableForItemCategory(theItem->category)[theItem->kind].identified || rogue.playbackOmniscience)) { strcat(buf, tableForItemCategory(theItem->category)[theItem->kind].description); if (theItem->category == POTION && theItem->kind == POTION_LIFE) { - sprintf(buf2, "\n\nIt will increase your maximum health by %s%i%%%s.", - goodColorEscape, - (player.info.maxHP + 10) * 100 / player.info.maxHP - 100, - whiteColorEscape); + sprintf(buf2, "\n\nIt will increase your maximum health by %s%i%%%s.", goodColorEscape, (player.info.maxHP + 10) * 100 / player.info.maxHP - 100, whiteColorEscape); strcat(buf, buf2); } } else { switch (theItem->category) { case POTION: - sprintf(buf2, "%s flask%s contain%s a swirling %s liquid. Who knows what %s will do when drunk or thrown?", - (singular ? "This" : "These"), - (singular ? "" : "s"), - (singular ? "s" : ""), - tableForItemCategory(theItem->category)[theItem->kind].flavor, - (singular ? "it" : "they")); + sprintf(buf2, "%s flask%s contain%s a swirling %s liquid. Who knows what %s will do when drunk or thrown?", (singular ? "This" : "These"), (singular ? "" : "s"), (singular ? "s" : ""), + tableForItemCategory(theItem->category)[theItem->kind].flavor, (singular ? "it" : "they")); break; case SCROLL: - sprintf(buf2, "%s parchment%s %s covered with indecipherable writing, and bear%s a title of \"%s.\" Who knows what %s will do when read aloud?", - (singular ? "This" : "These"), - (singular ? "" : "s"), - (singular ? "is" : "are"), - (singular ? "s" : ""), - tableForItemCategory(theItem->category)[theItem->kind].flavor, - (singular ? "it" : "they")); + sprintf(buf2, + "%s parchment%s %s covered with indecipherable writing, and bear%s a title of \"%s.\" Who knows " + "what %s will do when read aloud?", + (singular ? "This" : "These"), (singular ? "" : "s"), (singular ? "is" : "are"), (singular ? "s" : ""), tableForItemCategory(theItem->category)[theItem->kind].flavor, (singular ? "it" : "they")); break; case STAFF: - sprintf(buf2, "This gnarled %s staff is warm to the touch. Who knows what it will do when used?", - tableForItemCategory(theItem->category)[theItem->kind].flavor); + sprintf(buf2, "This gnarled %s staff is warm to the touch. Who knows what it will do when used?", tableForItemCategory(theItem->category)[theItem->kind].flavor); break; case WAND: - sprintf(buf2, "This thin %s wand is warm to the touch. Who knows what it will do when used?", - tableForItemCategory(theItem->category)[theItem->kind].flavor); + sprintf(buf2, "This thin %s wand is warm to the touch. Who knows what it will do when used?", tableForItemCategory(theItem->category)[theItem->kind].flavor); break; case RING: - sprintf(buf2, "This metal band is adorned with a%s %s gem that glitters in the darkness. Who knows what effect it has when worn? ", - isVowelish(tableForItemCategory(theItem->category)[theItem->kind].flavor) ? "n" : "", - tableForItemCategory(theItem->category)[theItem->kind].flavor); + sprintf(buf2, + "This metal band is adorned with a%s %s gem that glitters in the darkness. Who knows what effect " + "it has when worn? ", + isVowelish(tableForItemCategory(theItem->category)[theItem->kind].flavor) ? "n" : "", tableForItemCategory(theItem->category)[theItem->kind].flavor); break; case CHARM: // Should never be displayed. strcat(buf2, "What a perplexing charm!"); break; case AMULET: - strcpy(buf2, "Legends are told about this mysterious golden amulet, and legions of adventurers have perished in its pursuit. Unfathomable riches await anyone with the skill and ambition to carry it into the light of day."); + strcpy(buf2, "Legends are told about this mysterious golden amulet, and legions of adventurers have " + "perished in its pursuit. Unfathomable riches await anyone with the skill and ambition to " + "carry it into the light of day."); break; case GEM: - sprintf(buf2, "Faint golden lights swirl and fluoresce beneath the stone%s surface. Lumenstones are said to contain mysterious properties of untold power, but for you, they mean one thing: riches.", + sprintf(buf2, + "Faint golden lights swirl and fluoresce beneath the stone%s surface. Lumenstones are said to " + "contain mysterious properties of untold power, but for you, they mean one thing: riches.", (singular ? "'s" : "s'")); break; case KEY: @@ -1925,14 +1773,10 @@ void itemDetails(char *buf, item *theItem) { } if (carried && theItem->originDepth > 0) { - sprintf(buf2, " (You found %s%s on depth %i.) ", - singular ? "it" : "them", - // items in an item-choice vault are "keys", but are not a KEY - // we ignore any actual KEY, as those might not be on an altar - theItem->flags & ITEM_IS_KEY && !(theItem->category & KEY) - ? " in a vault" : "", - theItem->originDepth - ); + sprintf(buf2, " (You found %s%s on depth %i.) ", singular ? "it" : "them", + // items in an item-choice vault are "keys", but are not a KEY + // we ignore any actual KEY, as those might not be on an altar + theItem->flags & ITEM_IS_KEY && !(theItem->category & KEY) ? " in a vault" : "", theItem->originDepth); strcat(buf, buf2); } @@ -1940,9 +1784,7 @@ void itemDetails(char *buf, item *theItem) { switch (theItem->category) { case FOOD: - sprintf(buf2, "\n\nYou are %shungry enough to fully enjoy a %s.", - ((STOMACH_SIZE - player.status[STATUS_NUTRITION]) >= foodTable[theItem->kind].power ? "" : "not yet "), - foodTable[theItem->kind].name); + sprintf(buf2, "\n\nYou are %shungry enough to fully enjoy a %s.", ((STOMACH_SIZE - player.status[STATUS_NUTRITION]) >= foodTable[theItem->kind].power ? "" : "not yet "), foodTable[theItem->kind].name); strcat(buf, buf2); break; @@ -1952,76 +1794,44 @@ void itemDetails(char *buf, item *theItem) { if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { if (theItem->enchant1) { if (theItem->enchant1 > 0) { - sprintf(buf2, "\n\nThe %s bear%s an intrinsic enchantment of %s+%i%s", - theName, - (singular ? "s" : ""), - goodColorEscape, - theItem->enchant1, - whiteColorEscape); + sprintf(buf2, "\n\nThe %s bear%s an intrinsic enchantment of %s+%i%s", theName, (singular ? "s" : ""), goodColorEscape, theItem->enchant1, whiteColorEscape); } else { - sprintf(buf2, "\n\nThe %s bear%s an intrinsic penalty of %s%i%s", - theName, - (singular ? "s" : ""), - badColorEscape, - theItem->enchant1, - whiteColorEscape); + sprintf(buf2, "\n\nThe %s bear%s an intrinsic penalty of %s%i%s", theName, (singular ? "s" : ""), badColorEscape, theItem->enchant1, whiteColorEscape); } } else { - sprintf(buf2, "\n\nThe %s bear%s no intrinsic enchantment", - theName, - (singular ? "s" : "")); + sprintf(buf2, "\n\nThe %s bear%s no intrinsic enchantment", theName, (singular ? "s" : "")); } strcat(buf, buf2); if (strengthModifier(theItem)) { - sprintf(buf2, ", %s %s %s %s%s%+.2f%s because of your %s strength. ", - (theItem->enchant1 ? "and" : "but"), - (singular ? "carries" : "carry"), - (theItem->enchant1 && (theItem->enchant1 > 0) == (strengthModifier(theItem) > 0) ? "an additional" : "a"), - (strengthModifier(theItem) > 0 ? "bonus of " : "penalty of "), - (strengthModifier(theItem) > 0 ? goodColorEscape : badColorEscape), - strengthModifier(theItem) / (double) FP_FACTOR, - whiteColorEscape, - (strengthModifier(theItem) > 0 ? "excess" : "inadequate")); + sprintf(buf2, ", %s %s %s %s%s%+.2f%s because of your %s strength. ", (theItem->enchant1 ? "and" : "but"), (singular ? "carries" : "carry"), + (theItem->enchant1 && (theItem->enchant1 > 0) == (strengthModifier(theItem) > 0) ? "an additional" : "a"), (strengthModifier(theItem) > 0 ? "bonus of " : "penalty of "), + (strengthModifier(theItem) > 0 ? goodColorEscape : badColorEscape), strengthModifier(theItem) / (double)FP_FACTOR, whiteColorEscape, (strengthModifier(theItem) > 0 ? "excess" : "inadequate")); strcat(buf, buf2); } else { strcat(buf, ". "); } } else { if ((theItem->enchant1 > 0) && (theItem->flags & ITEM_MAGIC_DETECTED)) { - sprintf(buf2, "\n\nYou can feel an %saura of benevolent magic%s radiating from the %s. ", - goodColorEscape, - whiteColorEscape, - theName); + sprintf(buf2, "\n\nYou can feel an %saura of benevolent magic%s radiating from the %s. ", goodColorEscape, whiteColorEscape, theName); strcat(buf, buf2); } if (strengthModifier(theItem)) { - sprintf(buf2, "\n\nThe %s %s%s a %s%s%+.2f%s because of your %s strength. ", - theName, - ((theItem->enchant1 > 0) && (theItem->flags & ITEM_MAGIC_DETECTED) ? "also " : ""), - (singular ? "carries" : "carry"), - (strengthModifier(theItem) > 0 ? "bonus of " : "penalty of "), - (strengthModifier(theItem) > 0 ? goodColorEscape : badColorEscape), - strengthModifier(theItem) / (double) FP_FACTOR, - whiteColorEscape, + sprintf(buf2, "\n\nThe %s %s%s a %s%s%+.2f%s because of your %s strength. ", theName, ((theItem->enchant1 > 0) && (theItem->flags & ITEM_MAGIC_DETECTED) ? "also " : ""), (singular ? "carries" : "carry"), + (strengthModifier(theItem) > 0 ? "bonus of " : "penalty of "), (strengthModifier(theItem) > 0 ? goodColorEscape : badColorEscape), strengthModifier(theItem) / (double)FP_FACTOR, whiteColorEscape, (strengthModifier(theItem) > 0 ? "excess" : "inadequate")); strcat(buf, buf2); } if (theItem->category & WEAPON) { - sprintf(buf2, "It will reveal its secrets if you defeat %i%s %s with it. ", - theItem->charges, - (theItem->charges == gameConst->weaponKillsToAutoID ? "" : " more"), - (theItem->charges == 1 ? "enemy" : "enemies")); + sprintf(buf2, "It will reveal its secrets if you defeat %i%s %s with it. ", theItem->charges, (theItem->charges == gameConst->weaponKillsToAutoID ? "" : " more"), (theItem->charges == 1 ? "enemy" : "enemies")); } else { - sprintf(buf2, "It will reveal its secrets if worn for %i%s turn%s. ", - theItem->charges, - (theItem->charges == gameConst->armorDelayToAutoID ? "" : " more"), - (theItem->charges == 1 ? "" : "s")); + sprintf(buf2, "It will reveal its secrets if worn for %i%s turn%s. ", theItem->charges, (theItem->charges == gameConst->armorDelayToAutoID ? "" : " more"), (theItem->charges == 1 ? "" : "s")); } strcat(buf, buf2); } - // Display the known percentage by which the armor/weapon will increase/decrease accuracy/damage/defense if not already equipped. + // Display the known percentage by which the armor/weapon will increase/decrease accuracy/damage/defense if not + // already equipped. if (!(theItem->flags & ITEM_EQUIPPED)) { if (theItem->category & WEAPON) { current = player.info.accuracy; @@ -2041,25 +1851,20 @@ void itemDetails(char *buf, item *theItem) { new = player.info.accuracy; newDamage = (theItem->damage.lowerBound + theItem->damage.upperBound) * FP_FACTOR / 2; if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { - new = new * accuracyFraction(netEnchant(theItem)) / FP_FACTOR; + new = new *accuracyFraction(netEnchant(theItem)) / FP_FACTOR; newDamage = newDamage * damageFraction(netEnchant(theItem)) / FP_FACTOR; } else { - new = new * accuracyFraction(strengthModifier(theItem)) / FP_FACTOR; + new = new *accuracyFraction(strengthModifier(theItem)) / FP_FACTOR; newDamage = newDamage * damageFraction(strengthModifier(theItem)) / FP_FACTOR; } - accuracyChange = (new * 100 / current) - 100; - damageChange = (newDamage * 100 / currentDamage) - 100; - sprintf(buf2, "Wielding the %s%s will %s your current accuracy by %s%i%%%s, and will %s your current damage by %s%i%%%s. ", - theName, - ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) ? "" : ", assuming it has no hidden properties,", - (((short) accuracyChange) < 0) ? "decrease" : "increase", - (((short) accuracyChange) < 0) ? badColorEscape : (accuracyChange > 0 ? goodColorEscape : ""), - abs((short) accuracyChange), - whiteColorEscape, - (((short) damageChange) < 0) ? "decrease" : "increase", - (((short) damageChange) < 0) ? badColorEscape : (damageChange > 0 ? goodColorEscape : ""), - abs((short) damageChange), - whiteColorEscape); + accuracyChange = (new * 100 / current) - 100; + damageChange = (newDamage * 100 / currentDamage) - 100; + sprintf(buf2, + "Wielding the %s%s will %s your current accuracy by %s%i%%%s, and will %s your current damage " + "by %s%i%%%s. ", + theName, ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) ? "" : ", assuming it has no hidden properties,", (((short)accuracyChange) < 0) ? "decrease" : "increase", + (((short)accuracyChange) < 0) ? badColorEscape : (accuracyChange > 0 ? goodColorEscape : ""), abs((short)accuracyChange), whiteColorEscape, (((short)damageChange) < 0) ? "decrease" : "increase", + (((short)damageChange) < 0) ? badColorEscape : (damageChange > 0 ? goodColorEscape : ""), abs((short)damageChange), whiteColorEscape); } else { new = 0; @@ -2073,40 +1878,27 @@ void itemDetails(char *buf, item *theItem) { new = max(0, new); - sprintf(buf2, "Wearing the %s%s will result in an armor rating of %s%i%s. ", - theName, - ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) ? "" : ", assuming it has no hidden properties,", - (new > displayedArmorValue() ? goodColorEscape : (new < displayedArmorValue() ? badColorEscape : whiteColorEscape)), - new, whiteColorEscape); + sprintf(buf2, "Wearing the %s%s will result in an armor rating of %s%i%s. ", theName, ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) ? "" : ", assuming it has no hidden properties,", + (new > displayedArmorValue() ? goodColorEscape : (new < displayedArmorValue() ? badColorEscape : whiteColorEscape)), new, whiteColorEscape); } strcat(buf, buf2); } // protected? if (theItem->flags & ITEM_PROTECTED) { - sprintf(buf2, "%sThe %s cannot be corroded by acid.%s ", - goodColorEscape, - theName, - whiteColorEscape); + sprintf(buf2, "%sThe %s cannot be corroded by acid.%s ", goodColorEscape, theName, whiteColorEscape); strcat(buf, buf2); } // heavy armor? current = armorStealthAdjustment(rogue.armor); - if ((theItem->category & ARMOR) - && !(theItem->flags & ITEM_EQUIPPED) - && (current != armorStealthAdjustment(theItem))) { + if ((theItem->category & ARMOR) && !(theItem->flags & ITEM_EQUIPPED) && (current != armorStealthAdjustment(theItem))) { new = armorStealthAdjustment(theItem); if (rogue.armor) { new -= armorStealthAdjustment(rogue.armor); } - sprintf(buf2, "Equipping the %s will %s%s your stealth range by %i%s. ", - theName, - new > 0 ? badColorEscape : goodColorEscape, - new > 0 ? "increase" : "decrease", - abs(new), - whiteColorEscape); + sprintf(buf2, "Equipping the %s will %s%s your stealth range by %i%s. ", theName, new > 0 ? badColorEscape : goodColorEscape, new > 0 ? "increase" : "decrease", abs(new), whiteColorEscape); strcat(buf, buf2); } @@ -2115,50 +1907,43 @@ void itemDetails(char *buf, item *theItem) { // runic? if (theItem->flags & ITEM_RUNIC) { if ((theItem->flags & ITEM_RUNIC_IDENTIFIED) || rogue.playbackOmniscience) { - sprintf(buf2, "\n\nGlowing runes of %s adorn the %s. ", - weaponRunicNames[theItem->enchant2], - theName); + sprintf(buf2, "\n\nGlowing runes of %s adorn the %s. ", weaponRunicNames[theItem->enchant2], theName); strcat(buf, buf2); if (theItem->enchant2 == W_SLAYING) { describeMonsterClass(buf3, theItem->vorpalEnemy, false); - sprintf(buf2, "It will never fail to slay a%s %s in a single stroke. ", - (isVowelish(buf3) ? "n" : ""), - buf3); + sprintf(buf2, "It will never fail to slay a%s %s in a single stroke. ", (isVowelish(buf3) ? "n" : ""), buf3); strcat(buf, buf2); } else if (theItem->enchant2 == W_MULTIPLICITY) { if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { - sprintf(buf2, "%i%% of the time that it hits an enemy, %i spectral %s%s will spring into being with accuracy and attack power equal to your own, and will dissipate %i turns later. (If the %s is enchanted, %i image%s will appear %i%% of the time, and will last %i turns.)", - runicWeaponChance(theItem, false, 0), - weaponImageCount(enchant), - theName, - (weaponImageCount(enchant) > 1 ? "s" : ""), - weaponImageDuration(enchant), - theName, - weaponImageCount(enchant + enchantMagnitude() * enchantIncrement(theItem)), - (weaponImageCount(enchant + enchantMagnitude() * enchantIncrement(theItem)) > 1 ? "s" : ""), - runicWeaponChance(theItem, true, enchant + enchantMagnitude() * enchantIncrement(theItem)), - weaponImageDuration(enchant + enchantMagnitude() * enchantIncrement(theItem))); + sprintf(buf2, + "%i%% of the time that it hits an enemy, %i spectral %s%s will spring into being " + "with accuracy and attack power equal to your own, and will dissipate %i turns " + "later. (If the %s is enchanted, %i image%s will appear %i%% of the time, and will " + "last %i turns.)", + runicWeaponChance(theItem, false, 0), weaponImageCount(enchant), theName, (weaponImageCount(enchant) > 1 ? "s" : ""), weaponImageDuration(enchant), theName, + weaponImageCount(enchant + enchantMagnitude() * enchantIncrement(theItem)), (weaponImageCount(enchant + enchantMagnitude() * enchantIncrement(theItem)) > 1 ? "s" : ""), + runicWeaponChance(theItem, true, enchant + enchantMagnitude() * enchantIncrement(theItem)), weaponImageDuration(enchant + enchantMagnitude() * enchantIncrement(theItem))); } else { - sprintf(buf2, "Sometimes, when it hits an enemy, spectral %ss will spring into being with accuracy and attack power equal to your own, and will dissipate shortly thereafter.", + sprintf(buf2, + "Sometimes, when it hits an enemy, spectral %ss will spring into being with accuracy " + "and attack power equal to your own, and will dissipate shortly thereafter.", theName); } strcat(buf, buf2); } else { if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { - if (runicWeaponChance(theItem, false, 0) < 2 - && rogue.strength - player.weaknessAmount < theItem->strengthRequired) { + if (runicWeaponChance(theItem, false, 0) < 2 && rogue.strength - player.weaknessAmount < theItem->strengthRequired) { - strcpy(buf2, "Its runic effect will almost never activate because of your inadequate strength, but sometimes, when"); + strcpy(buf2, "Its runic effect will almost never activate because of your inadequate " + "strength, but sometimes, when"); } else { - sprintf(buf2, "%i%% of the time that", - runicWeaponChance(theItem, false, 0)); + sprintf(buf2, "%i%% of the time that", runicWeaponChance(theItem, false, 0)); } strcat(buf, buf2); } else { strcat(buf, "Sometimes, when"); } - sprintf(buf2, " it hits an enemy, %s", - weaponRunicEffectDescriptions[theItem->enchant2]); + sprintf(buf2, " it hits an enemy, %s", weaponRunicEffectDescriptions[theItem->enchant2]); strcat(buf, buf2); if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { @@ -2167,25 +1952,24 @@ void itemDetails(char *buf, item *theItem) { strcat(buf, ". "); break; case W_PARALYSIS: - sprintf(buf2, " for %i turns. ", - (int) (weaponParalysisDuration(enchant))); + sprintf(buf2, " for %i turns. ", (int)(weaponParalysisDuration(enchant))); strcat(buf, buf2); - nextLevelState = (int) (weaponParalysisDuration(enchant + enchantMagnitude() * enchantIncrement(theItem))); + nextLevelState = (int)(weaponParalysisDuration(enchant + enchantMagnitude() * enchantIncrement(theItem))); break; case W_SLOWING: - sprintf(buf2, " for %i turns. ", - weaponSlowDuration(enchant)); + sprintf(buf2, " for %i turns. ", weaponSlowDuration(enchant)); strcat(buf, buf2); nextLevelState = weaponSlowDuration(enchant + enchantMagnitude() * enchantIncrement(theItem)); break; case W_CONFUSION: - sprintf(buf2, " for %i turns. ", - weaponConfusionDuration(enchant)); + sprintf(buf2, " for %i turns. ", weaponConfusionDuration(enchant)); strcat(buf, buf2); nextLevelState = weaponConfusionDuration(enchant + enchantMagnitude() * enchantIncrement(theItem)); break; case W_FORCE: - sprintf(buf2, " up to %i spaces backward. If the enemy hits an obstruction, it (and any monster it hits) will take damage in proportion to the distance it flew. ", + sprintf(buf2, + " up to %i spaces backward. If the enemy hits an obstruction, it (and any " + "monster it hits) will take damage in proportion to the distance it flew. ", weaponForceDistance(enchant)); strcat(buf, buf2); nextLevelState = weaponForceDistance(enchant + enchantMagnitude() * enchantIncrement(theItem)); @@ -2200,19 +1984,14 @@ void itemDetails(char *buf, item *theItem) { break; } - if (((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) - && runicWeaponChance(theItem, false, 0) < runicWeaponChance(theItem, true, enchant + enchantMagnitude() * enchantIncrement(theItem))){ - sprintf(buf2, "(If the %s is enchanted, the chance will increase to %i%%", - theName, - runicWeaponChance(theItem, true, enchant + enchantMagnitude() * enchantIncrement(theItem))); + if (((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) && runicWeaponChance(theItem, false, 0) < runicWeaponChance(theItem, true, enchant + enchantMagnitude() * enchantIncrement(theItem))) { + sprintf(buf2, "(If the %s is enchanted, the chance will increase to %i%%", theName, runicWeaponChance(theItem, true, enchant + enchantMagnitude() * enchantIncrement(theItem))); strcat(buf, buf2); if (nextLevelState) { if (theItem->enchant2 == W_FORCE) { - sprintf(buf2, " and the distance will increase to %i.)", - nextLevelState); + sprintf(buf2, " and the distance will increase to %i.)", nextLevelState); } else { - sprintf(buf2, " and the duration will increase to %i turns.)", - nextLevelState); + sprintf(buf2, " and the duration will increase to %i turns.)", nextLevelState); } } else { strcpy(buf2, ".)"); @@ -2225,24 +2004,17 @@ void itemDetails(char *buf, item *theItem) { } } else if (theItem->flags & ITEM_IDENTIFIED) { - sprintf(buf2, "\n\nGlowing runes of an indecipherable language run down the length of the %s. ", - theName); + sprintf(buf2, "\n\nGlowing runes of an indecipherable language run down the length of the %s. ", theName); strcat(buf, buf2); } } // equipped? cursed? if (theItem->flags & ITEM_EQUIPPED) { - sprintf(buf2, "\n\nYou hold the %s at the ready%s. ", - theName, - ((theItem->flags & ITEM_CURSED) ? ", and because it is cursed, you are powerless to let go" : "")); + sprintf(buf2, "\n\nYou hold the %s at the ready%s. ", theName, ((theItem->flags & ITEM_CURSED) ? ", and because it is cursed, you are powerless to let go" : "")); strcat(buf, buf2); - } else if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAGIC_DETECTED)) || rogue.playbackOmniscience) - && (theItem->flags & ITEM_CURSED)) { - sprintf(buf2, "\n\n%sYou can feel a malevolent magic lurking within the %s.%s ", - badColorEscape, - theName, - whiteColorEscape); + } else if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAGIC_DETECTED)) || rogue.playbackOmniscience) && (theItem->flags & ITEM_CURSED)) { + sprintf(buf2, "\n\n%sYou can feel a malevolent magic lurking within the %s.%s ", badColorEscape, theName, whiteColorEscape); strcat(buf, buf2); } @@ -2251,82 +2023,86 @@ void itemDetails(char *buf, item *theItem) { // runic? if (theItem->flags & ITEM_RUNIC) { if ((theItem->flags & ITEM_RUNIC_IDENTIFIED) || rogue.playbackOmniscience) { - sprintf(buf2, "\n\nGlowing runes of %s adorn the %s. ", - armorRunicNames[theItem->enchant2], - theName); + sprintf(buf2, "\n\nGlowing runes of %s adorn the %s. ", armorRunicNames[theItem->enchant2], theName); strcat(buf, buf2); - // A_MULTIPLICITY, A_MUTUALITY, A_ABSORPTION, A_REPRISAL, A_IMMUNITY, A_REFLECTION, A_BURDEN, A_VULNERABILITY, A_IMMOLATION + // A_MULTIPLICITY, A_MUTUALITY, A_ABSORPTION, A_REPRISAL, A_IMMUNITY, A_REFLECTION, A_BURDEN, + // A_VULNERABILITY, A_IMMOLATION switch (theItem->enchant2) { case A_MULTIPLICITY: - sprintf(buf2, "When worn, 33%% of the time that an enemy's attack connects, %i allied spectral duplicate%s of your attacker will appear for 3 turns. ", - armorImageCount(enchant), - (armorImageCount(enchant) == 1 ? "" : "s")); + sprintf(buf2, + "When worn, 33%% of the time that an enemy's attack connects, %i allied spectral " + "duplicate%s of your attacker will appear for 3 turns. ", + armorImageCount(enchant), (armorImageCount(enchant) == 1 ? "" : "s")); if (armorImageCount(enchant + enchantMagnitude() * enchantIncrement(theItem)) > armorImageCount(enchant)) { - sprintf(buf3, "(If the %s is enchanted, the number of duplicates will increase to %i.) ", - theName, - (armorImageCount(enchant + enchantMagnitude() * enchantIncrement(theItem)))); + sprintf(buf3, "(If the %s is enchanted, the number of duplicates will increase to %i.) ", theName, (armorImageCount(enchant + enchantMagnitude() * enchantIncrement(theItem)))); strcat(buf2, buf3); } break; case A_MUTUALITY: - strcpy(buf2, "When worn, the damage that you incur from physical attacks will be split evenly among yourself and all other adjacent enemies. "); + strcpy(buf2, "When worn, the damage that you incur from physical attacks will be split evenly " + "among yourself and all other adjacent enemies. "); break; case A_ABSORPTION: if (theItem->flags & ITEM_IDENTIFIED) { - sprintf(buf2, "It will reduce the damage of inbound attacks by a random amount between 1 and %i, which is %i%% of your current maximum health. (If the %s is enchanted, this maximum amount will %s %i.) ", - (int) armorAbsorptionMax(enchant), - (int) (100 * armorAbsorptionMax(enchant) / player.info.maxHP), - theName, + sprintf(buf2, + "It will reduce the damage of inbound attacks by a random amount between 1 and %i, " + "which is %i%% of your current maximum health. (If the %s is enchanted, this maximum " + "amount will %s %i.) ", + (int)armorAbsorptionMax(enchant), (int)(100 * armorAbsorptionMax(enchant) / player.info.maxHP), theName, (armorAbsorptionMax(enchant) == armorAbsorptionMax(enchant + enchantIncrement(theItem)) ? "remain at" : "increase to"), - (int) armorAbsorptionMax(enchant + enchantMagnitude() * enchantIncrement(theItem))); + (int)armorAbsorptionMax(enchant + enchantMagnitude() * enchantIncrement(theItem))); } else { - strcpy(buf2, "It will reduce the damage of inbound attacks by a random amount determined by its enchantment level. "); + strcpy(buf2, "It will reduce the damage of inbound attacks by a random amount determined " + "by its enchantment level. "); } break; case A_REPRISAL: if (theItem->flags & ITEM_IDENTIFIED) { - sprintf(buf2, "Any enemy that attacks you will itself be wounded by %i%% of the damage that it inflicts. (If the %s is enchanted, this percentage will increase to %i%%.) ", - armorReprisalPercent(enchant), - theName, - armorReprisalPercent(enchant + enchantMagnitude() * enchantIncrement(theItem))); + sprintf(buf2, + "Any enemy that attacks you will itself be wounded by %i%% of the damage that it " + "inflicts. (If the %s is enchanted, this percentage will increase to %i%%.) ", + armorReprisalPercent(enchant), theName, armorReprisalPercent(enchant + enchantMagnitude() * enchantIncrement(theItem))); } else { - strcpy(buf2, "Any enemy that attacks you will itself be wounded by a percentage (determined by enchantment level) of the damage that it inflicts. "); + strcpy(buf2, "Any enemy that attacks you will itself be wounded by a percentage " + "(determined by enchantment level) of the damage that it inflicts. "); } break; case A_IMMUNITY: describeMonsterClass(buf3, theItem->vorpalEnemy, false); - sprintf(buf2, "It offers complete protection from any attacking %s. ", - buf3); + sprintf(buf2, "It offers complete protection from any attacking %s. ", buf3); break; case A_REFLECTION: if (theItem->flags & ITEM_IDENTIFIED) { if (theItem->enchant1 > 0) { short reflectChance = reflectionChance(enchant); short reflectChance2 = reflectionChance(enchant + enchantMagnitude() * enchantIncrement(theItem)); - sprintf(buf2, "When worn, you will deflect %i%% of incoming spells -- including directly back at their source %i%% of the time. (If the armor is enchanted, these will increase to %i%% and %i%%.) ", - reflectChance, - reflectChance * reflectChance / 100, - reflectChance2, - reflectChance2 * reflectChance2 / 100); + sprintf(buf2, + "When worn, you will deflect %i%% of incoming spells -- including directly " + "back at their source %i%% of the time. (If the armor is enchanted, these will " + "increase to %i%% and %i%%.) ", + reflectChance, reflectChance * reflectChance / 100, reflectChance2, reflectChance2 * reflectChance2 / 100); } else if (theItem->enchant1 < 0) { short reflectChance = reflectionChance(enchant); short reflectChance2 = reflectionChance(enchant + enchantMagnitude() * enchantIncrement(theItem)); - sprintf(buf2, "When worn, %i%% of your own spells will deflect from their target -- including directly back at you %i%% of the time. (If the armor is enchanted, these will decrease to %i%% and %i%%.) ", - reflectChance, - reflectChance * reflectChance / 100, - reflectChance2, - reflectChance2 * reflectChance2 / 100); + sprintf(buf2, + "When worn, %i%% of your own spells will deflect from their target -- " + "including directly back at you %i%% of the time. (If the armor is enchanted, " + "these will decrease to %i%% and %i%%.) ", + reflectChance, reflectChance * reflectChance / 100, reflectChance2, reflectChance2 * reflectChance2 / 100); } } else { - strcpy(buf2, "When worn, you will deflect some percentage of incoming spells, determined by enchantment level. "); + strcpy(buf2, "When worn, you will deflect some percentage of incoming spells, determined " + "by enchantment level. "); } break; case A_RESPIRATION: - strcpy(buf2, "When worn, it will maintain a pocket of fresh air around you, rendering you immune to the effects of steam and all toxic gases. "); + strcpy(buf2, "When worn, it will maintain a pocket of fresh air around you, rendering you " + "immune to the effects of steam and all toxic gases. "); break; case A_DAMPENING: - strcpy(buf2, "When worn, it will safely absorb the concussive impact of any explosions (though you may still be burned). "); + strcpy(buf2, "When worn, it will safely absorb the concussive impact of any explosions (though " + "you may still be burned). "); break; case A_BURDEN: strcpy(buf2, "10% of the time it absorbs a blow, its strength requirement will permanently increase. "); @@ -2342,27 +2118,19 @@ void itemDetails(char *buf, item *theItem) { } strcat(buf, buf2); } else if (theItem->flags & ITEM_IDENTIFIED) { - sprintf(buf2, "\n\nGlowing runes of an indecipherable language spiral around the %s. ", - theName); + sprintf(buf2, "\n\nGlowing runes of an indecipherable language spiral around the %s. ", theName); strcat(buf, buf2); } } // equipped? cursed? if (theItem->flags & ITEM_EQUIPPED) { - sprintf(buf2, "\n\nYou are wearing the %s%s. ", - theName, - ((theItem->flags & ITEM_CURSED) ? ", and because it is cursed, you are powerless to remove it" : "")); + sprintf(buf2, "\n\nYou are wearing the %s%s. ", theName, ((theItem->flags & ITEM_CURSED) ? ", and because it is cursed, you are powerless to remove it" : "")); strcat(buf, buf2); - } else if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAGIC_DETECTED)) || rogue.playbackOmniscience) - && (theItem->flags & ITEM_CURSED)) { - sprintf(buf2, "\n\n%sYou can feel a malevolent magic lurking within the %s.%s ", - badColorEscape, - theName, - whiteColorEscape); + } else if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAGIC_DETECTED)) || rogue.playbackOmniscience) && (theItem->flags & ITEM_CURSED)) { + sprintf(buf2, "\n\n%sYou can feel a malevolent magic lurking within the %s.%s ", badColorEscape, theName, whiteColorEscape); strcat(buf, buf2); } - } break; @@ -2370,105 +2138,106 @@ void itemDetails(char *buf, item *theItem) { // charges new = apparentRingBonus(RING_WISDOM); - if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { - sprintf(buf2, "\n\nThe %s has %i charges remaining out of a maximum of %i charges, and%s recovers a charge in approximately %lli turns. ", - theName, - theItem->charges, - theItem->enchant1, - new == 0 ? "" : ", with your current rings,", - FP_DIV(staffChargeDuration(theItem), 10 * ringWisdomMultiplier(new * FP_FACTOR))); + if ((theItem->flags & ITEM_IDENTIFIED) || rogue.playbackOmniscience) { + sprintf(buf2, + "\n\nThe %s has %i charges remaining out of a maximum of %i charges, and%s recovers a charge in " + "approximately %lli turns. ", + theName, theItem->charges, theItem->enchant1, new == 0 ? "" : ", with your current rings,", FP_DIV(staffChargeDuration(theItem), 10 * ringWisdomMultiplier(new *FP_FACTOR))); strcat(buf, buf2); } else if (theItem->flags & ITEM_MAX_CHARGES_KNOWN) { - sprintf(buf2, "\n\nThe %s has a maximum of %i charges, and%s recovers a charge in approximately %lli turns. ", - theName, - theItem->enchant1, - new == 0 ? "" : ", with your current rings,", - FP_DIV(staffChargeDuration(theItem), 10 * ringWisdomMultiplier(new * FP_FACTOR))); + sprintf(buf2, "\n\nThe %s has a maximum of %i charges, and%s recovers a charge in approximately %lli turns. ", theName, theItem->enchant1, new == 0 ? "" : ", with your current rings,", + FP_DIV(staffChargeDuration(theItem), 10 * ringWisdomMultiplier(new *FP_FACTOR))); strcat(buf, buf2); } if (theItem->lastUsed[0] > 0 && theItem->lastUsed[1] > 0 && theItem->lastUsed[2] > 0) { - sprintf(buf2, "You last used it %li, %li and %li turns ago. ", - rogue.absoluteTurnNumber - theItem->lastUsed[0], - rogue.absoluteTurnNumber - theItem->lastUsed[1], - rogue.absoluteTurnNumber - theItem->lastUsed[2]); + sprintf(buf2, "You last used it %li, %li and %li turns ago. ", rogue.absoluteTurnNumber - theItem->lastUsed[0], rogue.absoluteTurnNumber - theItem->lastUsed[1], rogue.absoluteTurnNumber - theItem->lastUsed[2]); strcat(buf, buf2); } else if (theItem->lastUsed[0] > 0 && theItem->lastUsed[1] > 0) { - sprintf(buf2, "You last used it %li and %li turns ago. ", - rogue.absoluteTurnNumber - theItem->lastUsed[0], - rogue.absoluteTurnNumber - theItem->lastUsed[1]); + sprintf(buf2, "You last used it %li and %li turns ago. ", rogue.absoluteTurnNumber - theItem->lastUsed[0], rogue.absoluteTurnNumber - theItem->lastUsed[1]); strcat(buf, buf2); } else if (theItem->lastUsed[0] > 0) { turnsSinceLatestUse = rogue.absoluteTurnNumber - theItem->lastUsed[0]; - sprintf(buf2, "You last used it %li turn%s ago. ", - turnsSinceLatestUse, - turnsSinceLatestUse == 1 ? "" : "s"); + sprintf(buf2, "You last used it %li turn%s ago. ", turnsSinceLatestUse, turnsSinceLatestUse == 1 ? "" : "s"); strcat(buf, buf2); } // effect description - if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN)) && staffTable[theItem->kind].identified) - || rogue.playbackOmniscience) { + if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN)) && staffTable[theItem->kind].identified) || rogue.playbackOmniscience) { switch (theItem->kind) { case STAFF_LIGHTNING: - sprintf(buf2, "This staff deals damage to every creature in its line of fire; nothing is immune. (If the staff is enchanted, its average damage will increase by %i%%.)", - (int) (100 * (staffDamageLow(enchant + enchantMagnitude() * FP_FACTOR) + staffDamageHigh(enchant + enchantMagnitude() * FP_FACTOR)) / (staffDamageLow(enchant) + staffDamageHigh(enchant)) - 100)); + sprintf(buf2, + "This staff deals damage to every creature in its line of fire; nothing is immune. (If the " + "staff is enchanted, its average damage will increase by %i%%.)", + (int)(100 * (staffDamageLow(enchant + enchantMagnitude() * FP_FACTOR) + staffDamageHigh(enchant + enchantMagnitude() * FP_FACTOR)) / (staffDamageLow(enchant) + staffDamageHigh(enchant)) - 100)); break; case STAFF_FIRE: - sprintf(buf2, "This staff deals damage to any creature that it hits, unless the creature is immune to fire. (If the staff is enchanted, its average damage will increase by %i%%.) It also sets creatures and flammable terrain on fire.", - (int) (100 * (staffDamageLow(enchant + enchantMagnitude() * FP_FACTOR) + staffDamageHigh(enchant + enchantMagnitude() * FP_FACTOR)) / (staffDamageLow(enchant) + staffDamageHigh(enchant)) - 100)); + sprintf(buf2, + "This staff deals damage to any creature that it hits, unless the creature is immune to fire. " + "(If the staff is enchanted, its average damage will increase by %i%%.) It also sets creatures " + "and flammable terrain on fire.", + (int)(100 * (staffDamageLow(enchant + enchantMagnitude() * FP_FACTOR) + staffDamageHigh(enchant + enchantMagnitude() * FP_FACTOR)) / (staffDamageLow(enchant) + staffDamageHigh(enchant)) - 100)); break; case STAFF_POISON: - sprintf(buf2, "The bolt from this staff will poison any creature that it hits for %i turns. (If the staff is enchanted, this will increase to %i turns.)", - staffPoison(enchant), - staffPoison(enchant + enchantMagnitude() * FP_FACTOR)); + sprintf(buf2, + "The bolt from this staff will poison any creature that it hits for %i turns. (If the staff is " + "enchanted, this will increase to %i turns.)", + staffPoison(enchant), staffPoison(enchant + enchantMagnitude() * FP_FACTOR)); break; case STAFF_TUNNELING: - sprintf(buf2, "The bolt from this staff will dissolve %i layers of obstruction. (If the staff is enchanted, this will increase to %i layers.)", - theItem->enchant1, - theItem->enchant1 + enchantMagnitude()); + sprintf(buf2, + "The bolt from this staff will dissolve %i layers of obstruction. (If the staff is enchanted, " + "this will increase to %i layers.)", + theItem->enchant1, theItem->enchant1 + enchantMagnitude()); break; case STAFF_BLINKING: - sprintf(buf2, "This staff enables you to teleport up to %i spaces. (If the staff is enchanted, this will increase to %i spaces.)", - staffBlinkDistance(enchant), - staffBlinkDistance(enchant + enchantMagnitude() * FP_FACTOR)); + sprintf(buf2, + "This staff enables you to teleport up to %i spaces. (If the staff is enchanted, this will " + "increase to %i spaces.)", + staffBlinkDistance(enchant), staffBlinkDistance(enchant + enchantMagnitude() * FP_FACTOR)); break; case STAFF_ENTRANCEMENT: - sprintf(buf2, "This staff will compel its target to mirror your movements for %i turns. (If the staff is enchanted, this will increase to %i turns.)", - staffEntrancementDuration(enchant), - staffEntrancementDuration(enchant + enchantMagnitude() * FP_FACTOR)); + sprintf(buf2, + "This staff will compel its target to mirror your movements for %i turns. (If the staff is " + "enchanted, this will increase to %i turns.)", + staffEntrancementDuration(enchant), staffEntrancementDuration(enchant + enchantMagnitude() * FP_FACTOR)); break; case STAFF_HEALING: if (enchant / FP_FACTOR < 10) { - sprintf(buf2, "This staff will heal its target by %i%% of its maximum health. (If the staff is enchanted, this will increase to %i%%.)", - theItem->enchant1 * 10, - (theItem->enchant1 + enchantMagnitude()) * 10); + sprintf(buf2, + "This staff will heal its target by %i%% of its maximum health. (If the staff is " + "enchanted, this will increase to %i%%.)", + theItem->enchant1 * 10, (theItem->enchant1 + enchantMagnitude()) * 10); } else { strcpy(buf2, "This staff will completely heal its target."); } break; case STAFF_HASTE: - sprintf(buf2, "This staff will cause its target to move twice as fast for %i turns. (If the staff is enchanted, this will increase to %i turns.)", - staffHasteDuration(enchant), - staffHasteDuration(enchant + enchantMagnitude() * FP_FACTOR)); + sprintf(buf2, + "This staff will cause its target to move twice as fast for %i turns. (If the staff is " + "enchanted, this will increase to %i turns.)", + staffHasteDuration(enchant), staffHasteDuration(enchant + enchantMagnitude() * FP_FACTOR)); break; case STAFF_OBSTRUCTION: strcpy(buf2, ""); break; case STAFF_DISCORD: - sprintf(buf2, "This staff will cause discord for %i turns. (If the staff is enchanted, this will increase to %i turns.)", - staffDiscordDuration(enchant), - staffDiscordDuration(enchant + enchantMagnitude() * FP_FACTOR)); + sprintf(buf2, + "This staff will cause discord for %i turns. (If the staff is enchanted, this will increase to " + "%i turns.)", + staffDiscordDuration(enchant), staffDiscordDuration(enchant + enchantMagnitude() * FP_FACTOR)); break; case STAFF_CONJURATION: - sprintf(buf2, "%i phantom blades will be called into service. (If the staff is enchanted, this will increase to %i blades.)", - staffBladeCount(enchant), - staffBladeCount(enchant + enchantMagnitude() * FP_FACTOR)); + sprintf(buf2, + "%i phantom blades will be called into service. (If the staff is enchanted, this will increase " + "to %i blades.)", + staffBladeCount(enchant), staffBladeCount(enchant + enchantMagnitude() * FP_FACTOR)); break; case STAFF_PROTECTION: - sprintf(buf2, "This staff will shield a creature for up to 20 turns against up to %i damage. (If the staff is enchanted, this will increase to %i damage.)", - staffProtection(enchant) / 10, - staffProtection(enchant + enchantMagnitude() * FP_FACTOR) / 10); + sprintf(buf2, + "This staff will shield a creature for up to 20 turns against up to %i damage. (If the staff " + "is enchanted, this will increase to %i damage.)", + staffProtection(enchant) / 10, staffProtection(enchant + enchantMagnitude() * FP_FACTOR) / 10); break; default: strcpy(buf2, "No one knows what this staff does."); @@ -2485,32 +2254,25 @@ void itemDetails(char *buf, item *theItem) { strcat(buf, "\n\n"); if ((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN)) || rogue.playbackOmniscience) { if (theItem->charges) { - sprintf(buf2, "%i charge%s remain%s. Enchanting this wand will add %i charge%s.", - theItem->charges, - (theItem->charges == 1 ? "" : "s"), - (theItem->charges == 1 ? "s" : ""), - wandTable[theItem->kind].range.lowerBound * enchantMagnitude(), - (wandTable[theItem->kind].range.lowerBound * enchantMagnitude() == 1 ? "" : "s")); + sprintf(buf2, "%i charge%s remain%s. Enchanting this wand will add %i charge%s.", theItem->charges, (theItem->charges == 1 ? "" : "s"), (theItem->charges == 1 ? "s" : ""), + wandTable[theItem->kind].range.lowerBound * enchantMagnitude(), (wandTable[theItem->kind].range.lowerBound * enchantMagnitude() == 1 ? "" : "s")); } else { - sprintf(buf2, "No charges remain. Enchanting this wand will add %i charge%s.", - wandTable[theItem->kind].range.lowerBound * enchantMagnitude(), + sprintf(buf2, "No charges remain. Enchanting this wand will add %i charge%s.", wandTable[theItem->kind].range.lowerBound * enchantMagnitude(), (wandTable[theItem->kind].range.lowerBound * enchantMagnitude() == 1 ? "" : "s")); } } else { if (theItem->enchant2) { - sprintf(buf2, "You have used this wand %i time%s, but do not know how many charges, if any, remain.", - theItem->enchant2, - (theItem->enchant2 == 1 ? "" : "s")); + sprintf(buf2, "You have used this wand %i time%s, but do not know how many charges, if any, remain.", theItem->enchant2, (theItem->enchant2 == 1 ? "" : "s")); } else { strcpy(buf2, "You have not yet used this wand."); } if (wandTable[theItem->kind].identified) { strcat(buf, buf2); - sprintf(buf2, " Wands of this type can be found with %i to %i charges. Enchanting this wand will add %i charge%s.", - wandTable[theItem->kind].range.lowerBound, - wandTable[theItem->kind].range.upperBound, - wandTable[theItem->kind].range.lowerBound * enchantMagnitude(), + sprintf(buf2, + " Wands of this type can be found with %i to %i charges. Enchanting this wand will add %i " + "charge%s.", + wandTable[theItem->kind].range.lowerBound, wandTable[theItem->kind].range.upperBound, wandTable[theItem->kind].range.lowerBound * enchantMagnitude(), (wandTable[theItem->kind].range.lowerBound * enchantMagnitude() == 1 ? "" : "s")); } } @@ -2523,43 +2285,45 @@ void itemDetails(char *buf, item *theItem) { switch (theItem->kind) { case RING_CLAIRVOYANCE: if (theItem->enchant1 > 0) { - sprintf(buf2, "\n\nThis ring provides magical sight with a radius of %i. (If the ring is enchanted, this will increase to %i.)", - theItem->enchant1 + 1, - theItem->enchant1 + 1 + enchantMagnitude()); + sprintf(buf2, + "\n\nThis ring provides magical sight with a radius of %i. (If the ring is enchanted, " + "this will increase to %i.)", + theItem->enchant1 + 1, theItem->enchant1 + 1 + enchantMagnitude()); } else { - sprintf(buf2, "\n\nThis ring magically blinds you to a radius of %i. (If the ring is enchanted, this will decrease to %i.)", - (theItem->enchant1 * -1) + 1, - (theItem->enchant1 * -1) + 1 - enchantMagnitude()); + sprintf(buf2, + "\n\nThis ring magically blinds you to a radius of %i. (If the ring is enchanted, this " + "will decrease to %i.)", + (theItem->enchant1 * -1) + 1, (theItem->enchant1 * -1) + 1 - enchantMagnitude()); } strcat(buf, buf2); break; case RING_REGENERATION: - sprintf(buf2, "\n\nWith this ring equipped, you will regenerate all of your health in %li turns (instead of %li). (If the ring is enchanted, this will decrease to %li turns.)", - (long) (turnsForFullRegenInThousandths(enchant) / 1000), - (long) TURNS_FOR_FULL_REGEN, - (long) (turnsForFullRegenInThousandths(enchant + enchantMagnitude() * FP_FACTOR) / 1000)); + sprintf(buf2, + "\n\nWith this ring equipped, you will regenerate all of your health in %li turns (instead " + "of %li). (If the ring is enchanted, this will decrease to %li turns.)", + (long)(turnsForFullRegenInThousandths(enchant) / 1000), (long)TURNS_FOR_FULL_REGEN, (long)(turnsForFullRegenInThousandths(enchant + enchantMagnitude() * FP_FACTOR) / 1000)); strcat(buf, buf2); break; case RING_TRANSFERENCE: - sprintf(buf2, "\n\nDealing direct damage to a creature (whether in melee or otherwise) will %s you by %i%% of the damage dealt. (If the ring is enchanted, this will %s to %i%%.)", - (theItem->enchant1 >= 0 ? "heal" : "harm"), - abs(theItem->enchant1) * 5, - (theItem->enchant1 >= 0 ? "increase" : "decrease"), - abs(theItem->enchant1 + enchantMagnitude()) * 5); + sprintf(buf2, + "\n\nDealing direct damage to a creature (whether in melee or otherwise) will %s you by " + "%i%% of the damage dealt. (If the ring is enchanted, this will %s to %i%%.)", + (theItem->enchant1 >= 0 ? "heal" : "harm"), abs(theItem->enchant1) * 5, (theItem->enchant1 >= 0 ? "increase" : "decrease"), abs(theItem->enchant1 + enchantMagnitude()) * 5); strcat(buf, buf2); break; case RING_WISDOM: - sprintf(buf2, "\n\nWhen worn, your staffs will recharge at %i%% of their normal rate. (If the ring is enchanted, the rate will increase to %i%% of the normal rate.)", - (int) (100 * ringWisdomMultiplier(enchant) / FP_FACTOR), - (int) (100 * ringWisdomMultiplier(enchant + enchantMagnitude() * FP_FACTOR) / FP_FACTOR)); + sprintf(buf2, + "\n\nWhen worn, your staffs will recharge at %i%% of their normal rate. (If the ring is " + "enchanted, the rate will increase to %i%% of the normal rate.)", + (int)(100 * ringWisdomMultiplier(enchant) / FP_FACTOR), (int)(100 * ringWisdomMultiplier(enchant + enchantMagnitude() * FP_FACTOR) / FP_FACTOR)); strcat(buf, buf2); break; case RING_REAPING: - sprintf(buf2, "\n\nEach blow that you land with a weapon will %s your staffs and charms by 0-%i turns per point of damage dealt. (If the ring is enchanted, this will %s to 0-%i turns per point of damage.)", - (theItem->enchant1 >= 0 ? "recharge" : "drain"), - abs(theItem->enchant1), - (theItem->enchant1 >= 0 ? "increase" : "decrease"), - abs(theItem->enchant1 + enchantMagnitude())); + sprintf(buf2, + "\n\nEach blow that you land with a weapon will %s your staffs and charms by 0-%i turns " + "per point of damage dealt. (If the ring is enchanted, this will %s to 0-%i turns per " + "point of damage.)", + (theItem->enchant1 >= 0 ? "recharge" : "drain"), abs(theItem->enchant1), (theItem->enchant1 >= 0 ? "increase" : "decrease"), abs(theItem->enchant1 + enchantMagnitude())); strcat(buf, buf2); break; default: @@ -2567,10 +2331,7 @@ void itemDetails(char *buf, item *theItem) { } } } else { - sprintf(buf2, "\n\nIt will reveal its secrets if worn for %i%s turn%s", - theItem->charges, - (theItem->charges == gameConst->ringDelayToAutoID ? "" : " more"), - (theItem->charges == 1 ? "" : "s")); + sprintf(buf2, "\n\nIt will reveal its secrets if worn for %i%s turn%s", theItem->charges, (theItem->charges == gameConst->ringDelayToAutoID ? "" : " more"), (theItem->charges == 1 ? "" : "s")); strcat(buf, buf2); if (!(theItem->flags & ITEM_IDENTIFIED) && (theItem->charges < gameConst->ringDelayToAutoID || (theItem->flags & ITEM_MAGIC_DETECTED))) { @@ -2583,99 +2344,97 @@ void itemDetails(char *buf, item *theItem) { // equipped? cursed? if (theItem->flags & ITEM_EQUIPPED) { - sprintf(buf2, "\n\nThe %s is on your finger%s. ", - theName, - ((theItem->flags & ITEM_CURSED) ? ", and because it is cursed, you are powerless to remove it" : "")); + sprintf(buf2, "\n\nThe %s is on your finger%s. ", theName, ((theItem->flags & ITEM_CURSED) ? ", and because it is cursed, you are powerless to remove it" : "")); strcat(buf, buf2); - } else if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAGIC_DETECTED)) || rogue.playbackOmniscience) - && (theItem->flags & ITEM_CURSED)) { - sprintf(buf2, "\n\n%sYou can feel a malevolent magic lurking within the %s.%s ", - badColorEscape, - theName, - whiteColorEscape); + } else if (((theItem->flags & (ITEM_IDENTIFIED | ITEM_MAGIC_DETECTED)) || rogue.playbackOmniscience) && (theItem->flags & ITEM_CURSED)) { + sprintf(buf2, "\n\n%sYou can feel a malevolent magic lurking within the %s.%s ", badColorEscape, theName, whiteColorEscape); strcat(buf, buf2); } break; case CHARM: switch (theItem->kind) { case CHARM_HEALTH: - sprintf(buf2, "\n\nWhen used, the charm will heal %i%% of your health and recharge in %i turns. (If the charm is enchanted, it will heal %i%% of your health and recharge in %i turns.)", - charmHealing(enchant), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmHealing(enchant + enchantMagnitude() * FP_FACTOR), - charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); + sprintf(buf2, + "\n\nWhen used, the charm will heal %i%% of your health and recharge in %i turns. (If the charm is " + "enchanted, it will heal %i%% of your health and recharge in %i turns.)", + charmHealing(enchant), charmRechargeDelay(theItem->kind, theItem->enchant1), charmHealing(enchant + enchantMagnitude() * FP_FACTOR), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_PROTECTION: - sprintf(buf2, "\n\nWhen used, the charm will shield you for up to 20 turns for up to %i%% of your total health and recharge in %i turns. (If the charm is enchanted, it will shield up to %i%% of your total health and recharge in %i turns.)", - 100 * charmProtection(enchant) / 10 / player.info.maxHP, - charmRechargeDelay(theItem->kind, theItem->enchant1), - 100 * charmProtection(enchant + enchantMagnitude() * FP_FACTOR) / 10 / player.info.maxHP, + sprintf(buf2, + "\n\nWhen used, the charm will shield you for up to 20 turns for up to %i%% of your total health " + "and recharge in %i turns. (If the charm is enchanted, it will shield up to %i%% of your total " + "health and recharge in %i turns.)", + 100 * charmProtection(enchant) / 10 / player.info.maxHP, charmRechargeDelay(theItem->kind, theItem->enchant1), 100 * charmProtection(enchant + enchantMagnitude() * FP_FACTOR) / 10 / player.info.maxHP, charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_HASTE: - sprintf(buf2, "\n\nWhen used, the charm will haste you for %i turns and recharge in %i turns. (If the charm is enchanted, the haste will last %i turns and it will recharge in %i turns.)", - charmEffectDuration(theItem->kind, theItem->enchant1), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), + sprintf(buf2, + "\n\nWhen used, the charm will haste you for %i turns and recharge in %i turns. (If the charm is " + "enchanted, the haste will last %i turns and it will recharge in %i turns.)", + charmEffectDuration(theItem->kind, theItem->enchant1), charmRechargeDelay(theItem->kind, theItem->enchant1), charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_FIRE_IMMUNITY: - sprintf(buf2, "\n\nWhen used, the charm will grant you immunity to fire for %i turns and recharge in %i turns. (If the charm is enchanted, the immunity will last %i turns and it will recharge in %i turns.)", - charmEffectDuration(theItem->kind, theItem->enchant1), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), + sprintf(buf2, + "\n\nWhen used, the charm will grant you immunity to fire for %i turns and recharge in %i turns. " + "(If the charm is enchanted, the immunity will last %i turns and it will recharge in %i turns.)", + charmEffectDuration(theItem->kind, theItem->enchant1), charmRechargeDelay(theItem->kind, theItem->enchant1), charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_INVISIBILITY: - sprintf(buf2, "\n\nWhen used, the charm will turn you invisible for %i turns and recharge in %i turns. While invisible, monsters more than two spaces away cannot track you. (If the charm is enchanted, the invisibility will last %i turns and it will recharge in %i turns.)", - charmEffectDuration(theItem->kind, theItem->enchant1), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), + sprintf(buf2, + "\n\nWhen used, the charm will turn you invisible for %i turns and recharge in %i turns. While " + "invisible, monsters more than two spaces away cannot track you. (If the charm is enchanted, the " + "invisibility will last %i turns and it will recharge in %i turns.)", + charmEffectDuration(theItem->kind, theItem->enchant1), charmRechargeDelay(theItem->kind, theItem->enchant1), charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_TELEPATHY: - sprintf(buf2, "\n\nWhen used, the charm will grant you telepathy for %i turns and recharge in %i turns. (If the charm is enchanted, the telepathy will last %i turns and it will recharge in %i turns.)", - charmEffectDuration(theItem->kind, theItem->enchant1), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), + sprintf(buf2, + "\n\nWhen used, the charm will grant you telepathy for %i turns and recharge in %i turns. (If the " + "charm is enchanted, the telepathy will last %i turns and it will recharge in %i turns.)", + charmEffectDuration(theItem->kind, theItem->enchant1), charmRechargeDelay(theItem->kind, theItem->enchant1), charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_LEVITATION: - sprintf(buf2, "\n\nWhen used, the charm will lift you off the ground for %i turns and recharge in %i turns. (If the charm is enchanted, the levitation will last %i turns and it will recharge in %i turns.)", - charmEffectDuration(theItem->kind, theItem->enchant1), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), + sprintf(buf2, + "\n\nWhen used, the charm will lift you off the ground for %i turns and recharge in %i turns. (If " + "the charm is enchanted, the levitation will last %i turns and it will recharge in %i turns.)", + charmEffectDuration(theItem->kind, theItem->enchant1), charmRechargeDelay(theItem->kind, theItem->enchant1), charmEffectDuration(theItem->kind, theItem->enchant1 + enchantMagnitude()), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_SHATTERING: - sprintf(buf2, "\n\nWhen used, the charm will dissolve the nearby walls up to %i spaces away, and recharge in %i turns. (If the charm is enchanted, it will reach up to %i spaces and recharge in %i turns.)", - charmShattering(enchant), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmShattering(enchant + enchantMagnitude() * FP_FACTOR), + sprintf(buf2, + "\n\nWhen used, the charm will dissolve the nearby walls up to %i spaces away, and recharge in %i " + "turns. (If the charm is enchanted, it will reach up to %i spaces and recharge in %i turns.)", + charmShattering(enchant), charmRechargeDelay(theItem->kind, theItem->enchant1), charmShattering(enchant + enchantMagnitude() * FP_FACTOR), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_GUARDIAN: - sprintf(buf2, "\n\nWhen used, a guardian will materialize for %i turns, and the charm will recharge in %i turns. (If the charm is enchanted, the guardian will last for %i turns and the charm will recharge in %i turns.)", - charmGuardianLifespan(enchant), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmGuardianLifespan(enchant + enchantMagnitude() * FP_FACTOR), + sprintf(buf2, + "\n\nWhen used, a guardian will materialize for %i turns, and the charm will recharge in %i turns. (If " + "the charm is enchanted, the guardian will last for %i turns and the charm will recharge in %i turns.)", + charmGuardianLifespan(enchant), charmRechargeDelay(theItem->kind, theItem->enchant1), charmGuardianLifespan(enchant + enchantMagnitude() * FP_FACTOR), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_TELEPORTATION: - sprintf(buf2, "\n\nWhen used, the charm will teleport you elsewhere in the dungeon and recharge in %i turns. (If the charm is enchanted, it will recharge in %i turns.)", - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); + sprintf(buf2, + "\n\nWhen used, the charm will teleport you elsewhere in the dungeon and recharge in %i turns. (If " + "the charm is enchanted, it will recharge in %i turns.)", + charmRechargeDelay(theItem->kind, theItem->enchant1), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_RECHARGING: - sprintf(buf2, "\n\nWhen used, the charm will recharge your staffs (though not your wands or charms), after which it will recharge in %i turns. (If the charm is enchanted, it will recharge in %i turns.)", - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); + sprintf(buf2, + "\n\nWhen used, the charm will recharge your staffs (though not your wands or charms), after which " + "it will recharge in %i turns. (If the charm is enchanted, it will recharge in %i turns.)", + charmRechargeDelay(theItem->kind, theItem->enchant1), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; case CHARM_NEGATION: - sprintf(buf2, "\n\nWhen used, the charm will emit a wave of anti-magic up to %i spaces away, negating all magical effects on you and on creatures and dropped items in your field of view. It will recharge in %i turns. (If the charm is enchanted, it will reach up to %i spaces and recharge in %i turns.)", - charmNegationRadius(enchant), - charmRechargeDelay(theItem->kind, theItem->enchant1), - charmNegationRadius(enchant + enchantMagnitude() * FP_FACTOR), + sprintf(buf2, + "\n\nWhen used, the charm will emit a wave of anti-magic up to %i spaces away, negating all " + "magical effects on you and on creatures and dropped items in your field of view. It will recharge " + "in %i turns. (If the charm is enchanted, it will reach up to %i spaces and recharge in %i turns.)", + charmNegationRadius(enchant), charmRechargeDelay(theItem->kind, theItem->enchant1), charmNegationRadius(enchant + enchantMagnitude() * FP_FACTOR), charmRechargeDelay(theItem->kind, theItem->enchant1 + enchantMagnitude())); break; default: @@ -2689,24 +2448,19 @@ void itemDetails(char *buf, item *theItem) { } boolean displayMagicCharForItem(item *theItem) { - if (!(theItem->flags & ITEM_MAGIC_DETECTED) - || (theItem->category & PRENAMED_CATEGORY)) { + if (!(theItem->flags & ITEM_MAGIC_DETECTED) || (theItem->category & PRENAMED_CATEGORY)) { return false; } else { return true; } } -char displayInventory(unsigned short categoryMask, - unsigned long requiredFlags, - unsigned long forbiddenFlags, - boolean waitForAcknowledge, - boolean includeButtons) { +char displayInventory(unsigned short categoryMask, unsigned long requiredFlags, unsigned long forbiddenFlags, boolean waitForAcknowledge, boolean includeButtons) { item *theItem; short i, j, m, maxLength = 0, itemNumber, itemCount, equippedItemCount; short extraLineCount = 0; item *itemList[DROWS]; - char buf[COLS*3]; + char buf[COLS * 3]; char theKey; rogueEvent theEvent; boolean magicDetected, repeatDisplay; @@ -2717,12 +2471,7 @@ char displayInventory(unsigned short categoryMask, short actionKey = -1; color darkItemColor; - char whiteColorEscapeSequence[20], - grayColorEscapeSequence[20], - yellowColorEscapeSequence[20], - darkYellowColorEscapeSequence[20], - goodColorEscapeSequence[20], - badColorEscapeSequence[20]; + char whiteColorEscapeSequence[20], grayColorEscapeSequence[20], yellowColorEscapeSequence[20], darkYellowColorEscapeSequence[20], goodColorEscapeSequence[20], badColorEscapeSequence[20]; char *magicEscapePtr; assureCosmeticRNG; @@ -2794,7 +2543,7 @@ char displayInventory(unsigned short categoryMask, } // Initialize the buttons: - for (i=0; i < max(MAX_PACK_ITEMS, ROWS); i++) { + for (i = 0; i < max(MAX_PACK_ITEMS, ROWS); i++) { buttons[i].y = mapToWindowY(i + (equippedItemCount && i >= equippedItemCount ? 1 : 0)); buttons[i].buttonColor = black; buttons[i].opacity = INTERFACE_OPACITY; @@ -2802,7 +2551,7 @@ char displayInventory(unsigned short categoryMask, } // Now prepare the buttons. const char closeParen = KEYBOARD_LABELS ? ')' : ' '; - for (i=0; iinventoryLetter; buttons[i].hotkey[1] = theItem->inventoryLetter + 'A' - 'a'; - if ((theItem->category & categoryMask) && - !(~(theItem->flags) & requiredFlags) && - !(theItem->flags & forbiddenFlags)) { + if ((theItem->category & categoryMask) && !(~(theItem->flags) & requiredFlags) && !(theItem->flags & forbiddenFlags)) { buttons[i].flags |= (B_HOVER_ENABLED); } @@ -2823,8 +2570,7 @@ char displayInventory(unsigned short categoryMask, itemName(theItem, buf, true, true, (buttons[i].flags & B_HOVER_ENABLED) ? &white : &gray); upperCase(buf); - if ((theItem->flags & ITEM_MAGIC_DETECTED) - && !(theItem->category & AMULET)) { // Won't include food, keys, lumenstones or amulet. + if ((theItem->flags & ITEM_MAGIC_DETECTED) && !(theItem->category & AMULET)) { // Won't include food, keys, lumenstones or amulet. int polarity = itemMagicPolarity(theItem); if (polarity == 0) { @@ -2840,25 +2586,15 @@ char displayInventory(unsigned short categoryMask, // The first '*' is the magic detection symbol, e.g. '-' for non-magical. // The second '*' is the item character, e.g. ':' for food. - sprintf(buttons[i].text, " %c%c %s* %s* %s%s%s%s", - KEYBOARD_LABELS ? theItem->inventoryLetter : ' ', - (theItem->flags & ITEM_PROTECTED ? '}' : closeParen), - magicEscapePtr, - (buttons[i].flags & B_HOVER_ENABLED) ? yellowColorEscapeSequence : darkYellowColorEscapeSequence, - (buttons[i].flags & B_HOVER_ENABLED) ? whiteColorEscapeSequence : grayColorEscapeSequence, - buf, - grayColorEscapeSequence, + sprintf(buttons[i].text, " %c%c %s* %s* %s%s%s%s", KEYBOARD_LABELS ? theItem->inventoryLetter : ' ', (theItem->flags & ITEM_PROTECTED ? '}' : closeParen), magicEscapePtr, + (buttons[i].flags & B_HOVER_ENABLED) ? yellowColorEscapeSequence : darkYellowColorEscapeSequence, (buttons[i].flags & B_HOVER_ENABLED) ? whiteColorEscapeSequence : grayColorEscapeSequence, buf, grayColorEscapeSequence, (theItem->flags & ITEM_EQUIPPED ? ((theItem->category & WEAPON) ? " (in hand) " : " (worn) ") : "")); buttons[i].symbol[1] = theItem->displayChar; } else { sprintf(buttons[i].text, " %c%c %s%s* %s%s%s%s", // The '*' is the item character, e.g. ':' for food. - KEYBOARD_LABELS ? theItem->inventoryLetter : ' ', - (theItem->flags & ITEM_PROTECTED ? '}' : closeParen), + KEYBOARD_LABELS ? theItem->inventoryLetter : ' ', (theItem->flags & ITEM_PROTECTED ? '}' : closeParen), (magicDetected ? " " : ""), // For proper spacing when this item is not detected but another is. - (buttons[i].flags & B_HOVER_ENABLED) ? yellowColorEscapeSequence : darkYellowColorEscapeSequence, - (buttons[i].flags & B_HOVER_ENABLED) ? whiteColorEscapeSequence : grayColorEscapeSequence, - buf, - grayColorEscapeSequence, + (buttons[i].flags & B_HOVER_ENABLED) ? yellowColorEscapeSequence : darkYellowColorEscapeSequence, (buttons[i].flags & B_HOVER_ENABLED) ? whiteColorEscapeSequence : grayColorEscapeSequence, buf, grayColorEscapeSequence, (theItem->flags & ITEM_EQUIPPED ? ((theItem->category & WEAPON) ? " (in hand) " : " (worn) ") : "")); buttons[i].symbol[0] = theItem->displayChar; } @@ -2870,7 +2606,7 @@ char displayInventory(unsigned short categoryMask, // // itemNumber++; } - //printf("\nMaxlength: %i", maxLength); + // printf("\nMaxlength: %i", maxLength); itemCount = itemNumber; if (!itemNumber) { confirmMessages(); @@ -2882,43 +2618,32 @@ char displayInventory(unsigned short categoryMask, // Add the two extra lines as disabled buttons. itemSpaceRemaining = MAX_PACK_ITEMS - numberOfItemsInPack(); if (itemSpaceRemaining) { - sprintf(buttons[itemNumber + extraLineCount].text, "%s%s You have room for %i more item%s.", - grayColorEscapeSequence, - (magicDetected ? " " : ""), - itemSpaceRemaining, - (itemSpaceRemaining == 1 ? "" : "s")); + sprintf(buttons[itemNumber + extraLineCount].text, "%s%s You have room for %i more item%s.", grayColorEscapeSequence, (magicDetected ? " " : ""), itemSpaceRemaining, (itemSpaceRemaining == 1 ? "" : "s")); } else { - sprintf(buttons[itemNumber + extraLineCount].text, "%s%s Your pack is full.", - grayColorEscapeSequence, - (magicDetected ? " " : "")); + sprintf(buttons[itemNumber + extraLineCount].text, "%s%s Your pack is full.", grayColorEscapeSequence, (magicDetected ? " " : "")); } maxLength = max(maxLength, (strLenWithoutEscapes(buttons[itemNumber + extraLineCount].text))); extraLineCount++; - sprintf(buttons[itemNumber + extraLineCount].text, - KEYBOARD_LABELS ? "%s%s -- press (a-z) for more info -- " : "%s%s -- touch an item for more info -- ", - grayColorEscapeSequence, - (magicDetected ? " " : "")); + sprintf(buttons[itemNumber + extraLineCount].text, KEYBOARD_LABELS ? "%s%s -- press (a-z) for more info -- " : "%s%s -- touch an item for more info -- ", grayColorEscapeSequence, (magicDetected ? " " : "")); maxLength = max(maxLength, (strLenWithoutEscapes(buttons[itemNumber + extraLineCount].text))); extraLineCount++; } if (equippedItemCount) { // Add a separator button to fill in the blank line between equipped and unequipped items. - sprintf(buttons[itemNumber + extraLineCount].text, " %s%s---", - (magicDetected ? " " : ""), - grayColorEscapeSequence); + sprintf(buttons[itemNumber + extraLineCount].text, " %s%s---", (magicDetected ? " " : ""), grayColorEscapeSequence); buttons[itemNumber + extraLineCount].y = mapToWindowY(equippedItemCount); extraLineCount++; } - for (i=0; i < itemNumber + extraLineCount; i++) { + for (i = 0; i < itemNumber + extraLineCount; i++) { // Position the button. buttons[i].x = COLS - maxLength; // Pad the button label with space, so the button reaches to the right edge of the screen. m = strlen(buttons[i].text); - for (j=buttons[i].x + strLenWithoutEscapes(buttons[i].text); j < COLS; j++) { + for (j = buttons[i].x + strLenWithoutEscapes(buttons[i].text); j < COLS; j++) { buttons[i].text[m] = ' '; m++; } @@ -2946,16 +2671,12 @@ char displayInventory(unsigned short categoryMask, // Do the button loop. highlightItemLine = -1; - overlayDisplayBuffer(rbuf, NULL); // Remove the inventory display while the buttons are active, - // since they look the same and we don't want their opacities to stack. + overlayDisplayBuffer(rbuf, NULL); // Remove the inventory display while the buttons are active, + // since they look the same and we don't want their opacities to stack. highlightItemLine = buttonInputLoop(buttons, itemCount + extraLineCount + 2, // the 2 is for up/down hotkeys - COLS - maxLength, - mapToWindowY(0), - maxLength, - itemNumber + extraLineCount, - &theEvent); + COLS - maxLength, mapToWindowY(0), maxLength, itemNumber + extraLineCount, &theEvent); if (highlightItemLine == itemNumber + extraLineCount + 0) { // Up key highlightItemLine = itemNumber - 1; @@ -2981,9 +2702,9 @@ char displayInventory(unsigned short categoryMask, overlayDisplayBuffer(dbuf, NULL); - //buttons[highlightItemLine].buttonColor = interfaceBoxColor; + // buttons[highlightItemLine].buttonColor = interfaceBoxColor; drawButton(&(buttons[highlightItemLine]), BUTTON_PRESSED, NULL); - //buttons[highlightItemLine].buttonColor = black; + // buttons[highlightItemLine].buttonColor = black; if (theEvent.shiftKey || theEvent.controlKey || waitForAcknowledge) { // Display an information window about the item. @@ -3057,9 +2778,7 @@ char displayInventory(unsigned short categoryMask, return theKey; } -short numberOfMatchingPackItems(unsigned short categoryMask, - unsigned long requiredFlags, unsigned long forbiddenFlags, - boolean displayErrors) { +short numberOfMatchingPackItems(unsigned short categoryMask, unsigned long requiredFlags, unsigned long forbiddenFlags, boolean displayErrors) { item *theItem; short matchingItemCount = 0; @@ -3073,9 +2792,7 @@ short numberOfMatchingPackItems(unsigned short categoryMask, for (theItem = packItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { - if (theItem->category & categoryMask && - !(~(theItem->flags) & requiredFlags) && - !(theItem->flags & forbiddenFlags)) { + if (theItem->category & categoryMask && !(~(theItem->flags) & requiredFlags) && !(theItem->flags & forbiddenFlags)) { matchingItemCount++; } @@ -3129,7 +2846,7 @@ short displayedArmorValue() { } void strengthCheck(item *theItem, boolean noisy) { - char buf1[COLS], buf2[COLS*2]; + char buf1[COLS], buf2[COLS * 2]; short strengthDeficiency; updateEncumbrance(); @@ -3146,8 +2863,7 @@ void strengthCheck(item *theItem, boolean noisy) { strengthDeficiency = theItem->strengthRequired - max(0, rogue.strength - player.weaknessAmount); strcpy(buf1, ""); itemName(theItem, buf1, false, false, NULL); - sprintf(buf2, "You stagger under the weight of the %s; %i more strength would be ideal.", - buf1, strengthDeficiency); + sprintf(buf2, "You stagger under the weight of the %s; %i more strength would be ideal.", buf1, strengthDeficiency); message(buf2, 0); } } @@ -3164,8 +2880,7 @@ void equip(item *theItem) { command[c++] = EQUIP_KEY; if (!theItem) { - theItem = promptForItemOfType((WEAPON|ARMOR|RING), 0, ITEM_EQUIPPED, - KEYBOARD_LABELS ? "Equip what? (a-z, shift for more info; or to cancel)" : "Equip what?", true); + theItem = promptForItemOfType((WEAPON | ARMOR | RING), 0, ITEM_EQUIPPED, KEYBOARD_LABELS ? "Equip what? (a-z, shift for more info; or to cancel)" : "Equip what?", true); } if (theItem == NULL) { return; @@ -3174,7 +2889,7 @@ void equip(item *theItem) { theItem2 = NULL; command[c++] = theItem->inventoryLetter; - if (theItem->category & (WEAPON|ARMOR|RING)) { + if (theItem->category & (WEAPON | ARMOR | RING)) { if (theItem->category & RING) { if (theItem->flags & ITEM_EQUIPPED) { @@ -3183,8 +2898,7 @@ void equip(item *theItem) { return; } else if (rogue.ringLeft && rogue.ringRight) { confirmMessages(); - theItem2 = promptForItemOfType((RING), ITEM_EQUIPPED, 0, - "You are already wearing two rings; remove which first?", true); + theItem2 = promptForItemOfType((RING), ITEM_EQUIPPED, 0, "You are already wearing two rings; remove which first?", true); if (!theItem2 || theItem2->category != RING || !(theItem2->flags & ITEM_EQUIPPED)) { if (theItem2) { // No message if canceled or did an inventory action instead. message("Invalid entry.", 0); @@ -3233,10 +2947,9 @@ void equip(item *theItem) { boolean keyMatchesLocation(item *theItem, short x, short y) { short i; - if ((theItem->flags & ITEM_IS_KEY) - && theItem->originDepth == rogue.depthLevel) { + if ((theItem->flags & ITEM_IS_KEY) && theItem->originDepth == rogue.depthLevel) { - for (i=0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++) { + for (i = 0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++) { if (theItem->keyLoc[i].x == x && theItem->keyLoc[i].y == y) { return true; } else if (theItem->keyLoc[i].machine == pmap[x][y].machineNumber) { @@ -3262,10 +2975,7 @@ item *keyOnTileAt(short x, short y) { item *theItem; creature *monst; - if ((pmap[x][y].flags & HAS_PLAYER) - && player.loc.x == x - && player.loc.y == y - && keyInPackFor(x, y)) { + if ((pmap[x][y].flags & HAS_PLAYER) && player.loc.x == x && player.loc.y == y && keyInPackFor(x, y)) { return keyInPackFor(x, y); } @@ -3276,7 +2986,7 @@ item *keyOnTileAt(short x, short y) { } } if (pmap[x][y].flags & HAS_MONSTER) { - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); if (monst->carriedItem) { theItem = monst->carriedItem; if (keyMatchesLocation(theItem, x, y)) { @@ -3291,7 +3001,7 @@ item *keyOnTileAt(short x, short y) { void aggravateMonsters(short distance, short x, short y, const color *flashColor) { short i, j, **grid; - rogue.wpCoordinates[0] = (pos) { x, y }; + rogue.wpCoordinates[0] = (pos){x, y}; refreshWaypoint(0); grid = allocGrid(); @@ -3311,8 +3021,8 @@ void aggravateMonsters(short distance, short x, short y, const color *flashColor } } } - for (i=0; i= 0 && grid[i][j] <= distance) { scentMap[i][j] = 0; addScentToCell(i, j, 2 * grid[i][j]); @@ -3353,13 +3063,8 @@ short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos // Set of candidate waypoints strategically placed within a diamond shape. // For why they must be within a diamond, google "diamond-exit rule". const int numOffsets = 21; - const fixpt offsets[][2] = { - {50, 50}, // center of the square first (coordinates are in %) - {40, 40}, {60, 40}, {60, 60}, {40, 60}, - {50, 30}, {70, 50}, {50, 70}, {30, 50}, - {50, 20}, {80, 50}, {50, 80}, {20, 50}, - {50, 10}, {90, 50}, {50, 90}, {10, 50}, - {50, 1}, {99, 50}, {50, 99}, { 1, 50} }; + const fixpt offsets[][2] = {{50, 50}, // center of the square first (coordinates are in %) + {40, 40}, {60, 40}, {60, 60}, {40, 60}, {50, 30}, {70, 50}, {50, 70}, {30, 50}, {50, 20}, {80, 50}, {50, 80}, {20, 50}, {50, 10}, {90, 50}, {50, 90}, {10, 50}, {50, 1}, {99, 50}, {50, 99}, {1, 50}}; if (originLoc.x == targetLoc.x && originLoc.y == targetLoc.y) { listOfCoordinates[0] = INVALID_POS; @@ -3371,13 +3076,12 @@ short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos listLength = 0; - - // always shoot from the center of the origin cell - point[0] = originLoc.x * FP_FACTOR + FP_FACTOR/2; - point[1] = originLoc.y * FP_FACTOR + FP_FACTOR/2; - // vector to target - step[0] = targetLoc.x * FP_FACTOR + offsets[offset < numOffsets ? offset : bestOffset][0] * FP_FACTOR / 100 - point[0]; - step[1] = targetLoc.y * FP_FACTOR + offsets[offset < numOffsets ? offset : bestOffset][1] * FP_FACTOR / 100 - point[1]; + // always shoot from the center of the origin cell + point[0] = originLoc.x * FP_FACTOR + FP_FACTOR / 2; + point[1] = originLoc.y * FP_FACTOR + FP_FACTOR / 2; + // vector to target + step[0] = targetLoc.x * FP_FACTOR + offsets[offset < numOffsets ? offset : bestOffset][0] * FP_FACTOR / 100 - point[0]; + step[1] = targetLoc.y * FP_FACTOR + offsets[offset < numOffsets ? offset : bestOffset][1] * FP_FACTOR / 100 - point[1]; // normalize the step, to move exactly one row or column at a time fixpt m = max(llabs(step[0]), llabs(step[1])); @@ -3388,10 +3092,7 @@ short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos while (true) { point[0] += step[0]; point[1] += step[1]; - listOfCoordinates[listLength] = (pos){ - .x = (point[0] < 0 ? -1 : point[0] / FP_FACTOR), - .y = (point[1] < 0 ? -1 : point[1] / FP_FACTOR) - }; + listOfCoordinates[listLength] = (pos){.x = (point[0] < 0 ? -1 : point[0] / FP_FACTOR), .y = (point[1] < 0 ? -1 : point[1] / FP_FACTOR)}; if (!isPosInMap(listOfCoordinates[listLength])) break; listLength++; }; @@ -3418,10 +3119,8 @@ short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos boolean isCastByPlayer = (originLoc.x == player.loc.x && originLoc.y == player.loc.y); creature *caster = monsterAtLoc(originLoc); - creature *monst = monsterAtLoc((pos){ x, y }); - boolean isMonster = monst - && !(monst->bookkeepingFlags & MB_SUBMERGED) - && !monsterIsHidden(monst, caster); + creature *monst = monsterAtLoc((pos){x, y}); + boolean isMonster = monst && !(monst->bookkeepingFlags & MB_SUBMERGED) && !monsterIsHidden(monst, caster); boolean isEnemyOfCaster = (monst && caster && monstersAreEnemies(monst, caster)); boolean isAllyOfCaster = (monst && caster && monstersAreTeammates(monst, caster)); @@ -3431,16 +3130,15 @@ short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos // target reached? if (x == targetLoc.x && y == targetLoc.y) { - if ((!targetsEnemies && !targetsAllies) || - (targetsEnemies && isMonster && isEnemyOfCaster) || - (targetsAllies && isMonster && isAllyOfCaster)) { + if ((!targetsEnemies && !targetsAllies) || (targetsEnemies && isMonster && isEnemyOfCaster) || (targetsAllies && isMonster && isAllyOfCaster)) { // Big bonus for hitting the target, but that bonus // is lower if this path uses an unknown tile. score += passesThroughUnknown ? 2500 : 5000; } - break; // we don't care about anything beyond the target--if the player did, they would have selected a farther target + break; // we don't care about anything beyond the target--if the player did, they would have selected a + // farther target } // if the caster is the player, undiscovered cells don't count (lest we reveal something about them) @@ -3499,19 +3197,16 @@ short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos // or one space prior, where would it stop? // Takes into account the caster's knowledge; i.e. won't be blocked by monsters // that the caster is not aware of. -void getImpactLoc(pos *returnLoc, const pos originLoc, const pos targetLoc, - const short maxDistance, const boolean returnLastEmptySpace, const bolt *theBolt) { +void getImpactLoc(pos *returnLoc, const pos originLoc, const pos targetLoc, const short maxDistance, const boolean returnLastEmptySpace, const bolt *theBolt) { pos coords[DCOLS + 1]; short i, n; creature *monst; n = getLineCoordinates(coords, originLoc, targetLoc, theBolt); n = min(n, maxDistance); - for (i=0; ibookkeepingFlags & MB_SUBMERGED)) { + if (monst && !monsterIsHidden(monst, monsterAtLoc(originLoc)) && !(monst->bookkeepingFlags & MB_SUBMERGED)) { // Imaginary bolt hit the player or a monster. break; } @@ -3520,12 +3215,12 @@ void getImpactLoc(pos *returnLoc, const pos originLoc, const pos targetLoc, } } if (i == maxDistance) { - *returnLoc = coords[i-1]; + *returnLoc = coords[i - 1]; } else if (returnLastEmptySpace) { if (i == 0) { *returnLoc = originLoc; } else { - *returnLoc = coords[i-1]; + *returnLoc = coords[i - 1]; } } else { *returnLoc = coords[i]; @@ -3538,23 +3233,19 @@ void getImpactLoc(pos *returnLoc, const pos originLoc, const pos targetLoc, boolean impermissibleKinkBetween(short x1, short y1, short x2, short y2) { brogueAssert(coordinatesAreInMap(x1, y1)); brogueAssert(coordinatesAreInMap(x2, y2)); - if (cellHasTerrainFlag(x1, y1, T_OBSTRUCTS_PASSABILITY) - || cellHasTerrainFlag(x2, y2, T_OBSTRUCTS_PASSABILITY)) { + if (cellHasTerrainFlag(x1, y1, T_OBSTRUCTS_PASSABILITY) || cellHasTerrainFlag(x2, y2, T_OBSTRUCTS_PASSABILITY)) { // One of the two locations is obstructed. return false; } - if (abs(x1 - x2) != 1 - || abs(y1 - y2) != 1) { + if (abs(x1 - x2) != 1 || abs(y1 - y2) != 1) { // Not diagonally adjacent. return false; } - if (!cellHasTerrainFlag(x2, y1, T_OBSTRUCTS_PASSABILITY) - || !cellHasTerrainFlag(x1, y2, T_OBSTRUCTS_PASSABILITY)) { + if (!cellHasTerrainFlag(x2, y1, T_OBSTRUCTS_PASSABILITY) || !cellHasTerrainFlag(x1, y2, T_OBSTRUCTS_PASSABILITY)) { // At least one of the common neighbors isn't obstructed. return false; } - if (!cellHasTerrainFlag(x2, y1, T_OBSTRUCTS_DIAGONAL_MOVEMENT) - && !cellHasTerrainFlag(x1, y2, T_OBSTRUCTS_DIAGONAL_MOVEMENT)) { + if (!cellHasTerrainFlag(x2, y1, T_OBSTRUCTS_DIAGONAL_MOVEMENT) && !cellHasTerrainFlag(x1, y2, T_OBSTRUCTS_DIAGONAL_MOVEMENT)) { // Neither of the common neighbors obstructs diagonal movement. return false; } @@ -3587,24 +3278,21 @@ boolean tunnelize(short x, short y) { spawnDungeonFeature(x, y, &dungeonFeatureCatalog[DF_TUNNELIZE], true, false); if (pmap[x][y].flags & HAS_MONSTER) { // Kill turrets and sentinels if you tunnelize them. - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); if (monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) { inflictLethalDamage(NULL, monst); killCreature(monst, false); } } } - if (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_DIAGONAL_MOVEMENT) - && didSomething) { + if (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_DIAGONAL_MOVEMENT) && didSomething) { // Tunnel out any diagonal kinks between walls. for (dir = 0; dir < DIRECTION_COUNT; dir++) { x2 = x + nbDirs[dir][0]; y2 = y + nbDirs[dir][1]; - if (coordinatesAreInMap(x2, y2) - && impermissibleKinkBetween(x, y, x2, y2)) { + if (coordinatesAreInMap(x2, y2) && impermissibleKinkBetween(x, y, x2, y2)) { - if ((pmap[x][y2].flags & IMPREGNABLE) - || (!(pmap[x2][y].flags & IMPREGNABLE) && rand_percent(50))) { + if ((pmap[x][y2].flags & IMPREGNABLE) || (!(pmap[x2][y].flags & IMPREGNABLE) && rand_percent(50))) { tunnelize(x2, y); } else { @@ -3633,7 +3321,7 @@ boolean negate(creature *monst) { monst->wasNegated = true; } - if (monst->bookkeepingFlags & MB_SEIZING){ + if (monst->bookkeepingFlags & MB_SEIZING) { monst->bookkeepingFlags &= ~MB_SEIZING; negated = true; } @@ -3684,15 +3372,15 @@ boolean negate(creature *monst) { negated = true; } if (monst == &player) { - if (monst->status[STATUS_TELEPATHIC] > 1 ) { + if (monst->status[STATUS_TELEPATHIC] > 1) { monst->status[STATUS_TELEPATHIC] = 1; negated = true; } - if (monst->status[STATUS_MAGICAL_FEAR] > 1 ) { + if (monst->status[STATUS_MAGICAL_FEAR] > 1) { monst->status[STATUS_MAGICAL_FEAR] = 1; negated = true; } - if (monst->status[STATUS_LEVITATING] > 1 ) { + if (monst->status[STATUS_LEVITATING] > 1) { monst->status[STATUS_LEVITATING] = 1; negated = true; } @@ -3703,15 +3391,15 @@ boolean negate(creature *monst) { negated = true; } } else { - if (monst->status[STATUS_TELEPATHIC] > 0 ) { + if (monst->status[STATUS_TELEPATHIC] > 0) { monst->status[STATUS_TELEPATHIC] = 0; negated = true; } - if (monst->status[STATUS_MAGICAL_FEAR] > 0 ) { + if (monst->status[STATUS_MAGICAL_FEAR] > 0) { monst->status[STATUS_MAGICAL_FEAR] = 0; negated = true; } - if (monst->status[STATUS_LEVITATING] > 0 ) { + if (monst->status[STATUS_LEVITATING] > 0) { monst->status[STATUS_LEVITATING] = 0; negated = true; } @@ -3760,7 +3448,7 @@ boolean negate(creature *monst) { } } monst->newPowerCount = monst->totalPowerCount; // Allies can re-learn lost ability slots. - applyInstantTileEffectsToCreature(monst); // in case it should immediately die or fall into a chasm + applyInstantTileEffectsToCreature(monst); // in case it should immediately die or fall into a chasm } if (negated && monst != &player && !(monst->info.flags & MONST_DIES_IF_NEGATED)) { @@ -3794,14 +3482,13 @@ boolean polymorph(creature *monst) { return false; // Sorry, this is not Nethack. } - if (monst->creatureState == MONSTER_FLEEING - && (monst->info.flags & (MONST_MAINTAINS_DISTANCE | MONST_FLEES_NEAR_DEATH)) || (monst->info.abilityFlags & MA_HIT_STEAL_FLEE)) { + if (monst->creatureState == MONSTER_FLEEING && (monst->info.flags & (MONST_MAINTAINS_DISTANCE | MONST_FLEES_NEAR_DEATH)) || (monst->info.abilityFlags & MA_HIT_STEAL_FLEE)) { monst->creatureState = MONSTER_TRACKING_SCENT; monst->creatureMode = MODE_NORMAL; } - unAlly(monst); // Sorry, no cheap dragon allies. + unAlly(monst); // Sorry, no cheap dragon allies. monst->mutationIndex = -1; // Polymorph cures mutation -- basic science. // After polymorphing, don't "drop" any creature on death (e.g. phylactery, phoenix egg) @@ -3816,8 +3503,8 @@ boolean polymorph(creature *monst) { do { newMonsterIndex = rand_range(1, NUMBER_MONSTER_KINDS - 1); } while (monsterCatalog[newMonsterIndex].flags & (MONST_INANIMATE | MONST_NO_POLYMORPH) // Can't turn something into an inanimate object or lich/phoenix/warden. - || newMonsterIndex == monst->info.monsterID); // Can't stay the same monster. - monst->info = monsterCatalog[newMonsterIndex]; // Presto change-o! + || newMonsterIndex == monst->info.monsterID); // Can't stay the same monster. + monst->info = monsterCatalog[newMonsterIndex]; // Presto change-o! monst->info.turnsBetweenRegen *= 1000; monst->currentHP = max(1, max(healthFraction * monst->info.maxHP / 1000, monst->info.maxHP - previousDamageTaken)); @@ -3926,9 +3613,7 @@ void heal(creature *monst, short percent, boolean panacea) { } } } - if (canDirectlySeeMonster(monst) - && monst != &player - && !panacea) { + if (canDirectlySeeMonster(monst) && monst != &player && !panacea) { monsterName(monstName, monst, true); sprintf(buf, "%s looks healthier", monstName); @@ -4004,7 +3689,7 @@ void rechargeItems(unsigned long categories) { } } -//void causeFear(const char *emitterName) { +// void causeFear(const char *emitterName) { // creature *monst; // short numberOfMonsters = 0; // char buf[DCOLS*3], mName[DCOLS]; @@ -4044,8 +3729,7 @@ void negationBlast(const char *emitterName, const short distance) { flashMonster(&player, &pink, 100); for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); - if ((pmapAt(monst->loc)->flags & IN_FIELD_OF_VIEW) - && (player.loc.x - monst->loc.x) * (player.loc.x - monst->loc.x) + (player.loc.y - monst->loc.y) * (player.loc.y - monst->loc.y) <= distance * distance) { + if ((pmapAt(monst->loc)->flags & IN_FIELD_OF_VIEW) && (player.loc.x - monst->loc.x) * (player.loc.x - monst->loc.x) + (player.loc.y - monst->loc.y) * (player.loc.y - monst->loc.y) <= distance * distance) { if (canSeeMonster(monst)) { flashMonster(monst, &pink, 100); @@ -4054,8 +3738,7 @@ void negationBlast(const char *emitterName, const short distance) { } } for (theItem = floorItems; theItem != NULL; theItem = theItem->nextItem) { - if ((pmapAt(theItem->loc)->flags & IN_FIELD_OF_VIEW) - && (player.loc.x - theItem->loc.x) * (player.loc.x - theItem->loc.x) + (player.loc.y - theItem->loc.y) * (player.loc.y - theItem->loc.y) <= distance * distance) { + if ((pmapAt(theItem->loc)->flags & IN_FIELD_OF_VIEW) && (player.loc.x - theItem->loc.x) * (player.loc.x - theItem->loc.x) + (player.loc.y - theItem->loc.y) * (player.loc.y - theItem->loc.y) <= distance * distance) { theItem->flags &= ~(ITEM_MAGIC_DETECTED | ITEM_CURSED); switch (theItem->category) { @@ -4097,8 +3780,7 @@ void discordBlast(const char *emitterName, const short distance) { colorFlash(&discordColor, 0, IN_FIELD_OF_VIEW, 3 + distance / 5, distance, player.loc.x, player.loc.y); for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); - if ((pmapAt(monst->loc)->flags & IN_FIELD_OF_VIEW) - && (player.loc.x - monst->loc.x) * (player.loc.x - monst->loc.x) + (player.loc.y - monst->loc.y) * (player.loc.y - monst->loc.y) <= distance * distance) { + if ((pmapAt(monst->loc)->flags & IN_FIELD_OF_VIEW) && (player.loc.x - monst->loc.x) * (player.loc.x - monst->loc.x) + (player.loc.y - monst->loc.y) * (player.loc.y - monst->loc.y) <= distance * distance) { if (!(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { if (canSeeMonster(monst)) { @@ -4115,10 +3797,9 @@ void crystalize(short radius) { short i, j; creature *monst; - for (i=0; iinfo.flags & MONST_ATTACKABLE_THRU_WALLS) { inflictLethalDamage(NULL, monst); killCreature(monst, false); @@ -4170,9 +3851,7 @@ boolean projectileReflects(creature *attacker, creature *defender) { fixpt netReflectionLevel; // immunity armor always reflects its vorpal enemy's projectiles - if (defender == &player && rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && rogue.armor->enchant2 == A_IMMUNITY - && monsterIsInClass(attacker, rogue.armor->vorpalEnemy) - && monstersAreEnemies(attacker, defender)) { + if (defender == &player && rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && rogue.armor->enchant2 == A_IMMUNITY && monsterIsInClass(attacker, rogue.armor->vorpalEnemy) && monstersAreEnemies(attacker, defender)) { return true; } @@ -4203,8 +3882,7 @@ boolean projectileReflects(creature *attacker, creature *defender) { // which diverges from the existing path at kinkCell, // and then returns the path length of the reflected path. short reflectBolt(short targetX, short targetY, pos listOfCoordinates[], short kinkCell, boolean retracePath) { - boolean needRandomTarget = (targetX < 0 || targetY < 0 - || (targetX == listOfCoordinates[kinkCell].x && targetY == listOfCoordinates[kinkCell].y)); + boolean needRandomTarget = (targetX < 0 || targetY < 0 || (targetX == listOfCoordinates[kinkCell].x && targetY == listOfCoordinates[kinkCell].y)); short finalLength; if (retracePath) { @@ -4221,16 +3899,13 @@ short reflectBolt(short targetX, short targetY, pos listOfCoordinates[], short k // (2,3) + ((2,3) - (0,0)) = (4,6). pos origin = listOfCoordinates[2 * kinkCell]; - pos target = (pos){ - .x = targetX + (targetX - listOfCoordinates[kinkCell].x), - .y = targetY + (targetY - listOfCoordinates[kinkCell].y) - }; + pos target = (pos){.x = targetX + (targetX - listOfCoordinates[kinkCell].x), .y = targetY + (targetY - listOfCoordinates[kinkCell].y)}; pos newPath[DCOLS]; // (NULL because the reflected bolt is not under the caster's control, so its path should not be tuned) const short newPathLength = getLineCoordinates(newPath, origin, target, NULL); - for (int k=0; k<=newPathLength; k++) { + for (int k = 0; k <= newPathLength; k++) { listOfCoordinates[2 * kinkCell + k + 1] = newPath[k]; } finalLength = 2 * kinkCell + newPathLength + 1; @@ -4246,11 +3921,10 @@ short reflectBolt(short targetX, short targetY, pos listOfCoordinates[], short k target.x += listOfCoordinates[kinkCell].x; target.y += listOfCoordinates[kinkCell].y; } else { - target = (pos){ .x = targetX, .y = targetY }; + target = (pos){.x = targetX, .y = targetY}; } newPathLength = getLineCoordinates(newPath, listOfCoordinates[kinkCell], target, NULL); - if (newPathLength > 0 - && !cellHasTerrainFlag(newPath[0].x, newPath[0].y, (T_OBSTRUCTS_VISION | T_OBSTRUCTS_PASSABILITY))) { + if (newPathLength > 0 && !cellHasTerrainFlag(newPath[0].x, newPath[0].y, (T_OBSTRUCTS_VISION | T_OBSTRUCTS_PASSABILITY))) { needRandomTarget = false; } @@ -4287,11 +3961,11 @@ void beckonMonster(creature *monst, short x, short y) { freeCaptive(monst); } pos from = monst->loc; - pos to = (pos){ .x = x, .y = y }; + pos to = (pos){.x = x, .y = y}; theBolt.magnitude = max(1, (distanceBetween((pos){x, y}, monst->loc) - 2) / 2); zap(from, to, &theBolt, false, true); - if (monst->ticksUntilTurn < player.attackSpeed+1) { - monst->ticksUntilTurn = player.attackSpeed+1; + if (monst->ticksUntilTurn < player.attackSpeed + 1) { + monst->ticksUntilTurn = player.attackSpeed + 1; } } @@ -4320,11 +3994,9 @@ enum boltType boltForItem(item *theItem) { // *autoID will be set to true. (AutoID can be null.) // If the effect causes the level's lighting or vision to change, *lightingChanged // will be set to true. (LightingChanged can be null.) -boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, - boolean boltInView, boolean alreadyReflected, - boolean *autoID, boolean *lightingChanged) { +boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, boolean boltInView, boolean alreadyReflected, boolean *autoID, boolean *lightingChanged) { char buf[COLS], monstName[COLS]; - creature *monst; // Creature being hit by the bolt, if any. + creature *monst; // Creature being hit by the bolt, if any. creature *newMonst; // Utility variable for plenty boolean terminateBolt = false; boolean negated = false; @@ -4335,14 +4007,13 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, // Handle collisions with monsters. - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); if (monst && !(monst->bookkeepingFlags & MB_SUBMERGED)) { monsterName(monstName, monst, true); - switch(theBolt->boltEffect) { + switch (theBolt->boltEffect) { case BE_ATTACK: - if (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) - || (monst->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { + if (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) || (monst->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { attack(caster, monst, false); if (autoID) { @@ -4354,15 +4025,10 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, if (autoID) { *autoID = true; } - if (((theBolt->flags & BF_FIERY) && monst->status[STATUS_IMMUNE_TO_FIRE] > 0) - || (monst->info.flags & MONST_INVULNERABLE)) { + if (((theBolt->flags & BF_FIERY) && monst->status[STATUS_IMMUNE_TO_FIRE] > 0) || (monst->info.flags & MONST_INVULNERABLE)) { if (canSeeMonster(monst)) { - sprintf(buf, "%s ignore%s %s %s", - monstName, - (monst == &player ? "" : "s"), - canSeeMonster(caster) ? "the" : "a", - theBolt->name); + sprintf(buf, "%s ignore%s %s %s", monstName, (monst == &player ? "" : "s"), canSeeMonster(caster) ? "the" : "a", theBolt->name); combatMessage(buf, 0); } } else if (inflictDamage(caster, monst, staffDamage(theBolt->magnitude * FP_FACTOR), theBolt->backColor, false)) { @@ -4377,11 +4043,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, return true; } if (boltInView || canSeeMonster(monst)) { - sprintf(buf, "%s %s %s %s", - canSeeMonster(caster) ? "the" : "a", - theBolt->name, - ((monst->info.flags & MONST_INANIMATE) ? "destroys" : "kills"), - monstName); + sprintf(buf, "%s %s %s %s", canSeeMonster(caster) ? "the" : "a", theBolt->name, ((monst->info.flags & MONST_INANIMATE) ? "destroys" : "kills"), monstName); combatMessage(buf, messageColorFromVictim(monst)); } else { sprintf(buf, "you hear %s %s", monstName, ((monst->info.flags & MONST_INANIMATE) ? "get destroyed" : "die")); @@ -4390,25 +4052,19 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, killCreature(monst, false); } else { // monster lives - if (monst->creatureMode != MODE_PERM_FLEEING - && monst->creatureState != MONSTER_ALLY - && (monst->creatureState != MONSTER_FLEEING || monst->status[STATUS_MAGICAL_FEAR])) { + if (monst->creatureMode != MODE_PERM_FLEEING && monst->creatureState != MONSTER_ALLY && (monst->creatureState != MONSTER_FLEEING || monst->status[STATUS_MAGICAL_FEAR])) { monst->creatureState = MONSTER_TRACKING_SCENT; monst->status[STATUS_MAGICAL_FEAR] = 0; } if (boltInView) { - sprintf(buf, "%s %s hits %s", - canSeeMonster(caster) ? "the" : "a", - theBolt->name, - monstName); + sprintf(buf, "%s %s hits %s", canSeeMonster(caster) ? "the" : "a", theBolt->name, monstName); combatMessage(buf, messageColorFromVictim(monst)); } if (theBolt->flags & BF_FIERY) { exposeCreatureToFire(monst); } - if (!alreadyReflected - || caster != &player) { + if (!alreadyReflected || caster != &player) { moralAttack(caster, monst); } } @@ -4425,9 +4081,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, } break; case BE_BECKONING: - if (!(monst->info.flags & MONST_IMMOBILE) - && caster - && distanceBetween(caster->loc, monst->loc) > 1) { + if (!(monst->info.flags & MONST_IMMOBILE) && caster && distanceBetween(caster->loc, monst->loc) > 1) { if (canSeeMonster(monst) && autoID) { *autoID = true; @@ -4476,7 +4130,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, // domination succeeded monst->status[STATUS_DISCORDANT] = 0; becomeAllyWith(monst); - //refreshSideBar(-1, -1, false); + // refreshSideBar(-1, -1, false); refreshDungeonCell(monst->loc.x, monst->loc.y); if (canSeeMonster(monst)) { if (autoID) { @@ -4508,8 +4162,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, break; case BE_EMPOWERMENT: - if (monst != &player - && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { + if (monst != &player && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { empowerMonster(monst); createFlare(monst->loc.x, monst->loc.y, EMPOWERMENT_LIGHT); @@ -4529,9 +4182,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, *autoID = true; } if (monst != &player) { - sprintf(buf, "%s %s %s sick", - monstName, - (monst == &player ? "feel" : "looks"), + sprintf(buf, "%s %s %s sick", monstName, (monst == &player ? "feel" : "looks"), (monst->status[STATUS_POISONED] * monst->poisonAmount >= monst->currentHP && !player.status[STATUS_HALLUCINATING] ? "fatally" : "very")); combatMessage(buf, messageColorFromVictim(monst)); } @@ -4588,8 +4239,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, break; case BE_DISCORD: if (!(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE))) { - monst->status[STATUS_DISCORDANT] = monst->maxStatus[STATUS_DISCORDANT] = max(staffDiscordDuration(theBolt->magnitude * FP_FACTOR), - monst->status[STATUS_DISCORDANT]); + monst->status[STATUS_DISCORDANT] = monst->maxStatus[STATUS_DISCORDANT] = max(staffDiscordDuration(theBolt->magnitude * FP_FACTOR), monst->status[STATUS_DISCORDANT]); if (canSeeMonster(monst)) { if (boltCatalog[BOLT_DISCORD].backColor) { flashMonster(monst, boltCatalog[BOLT_DISCORD].backColor, 100); @@ -4640,8 +4290,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, spawnDungeonFeature(x, y, &dungeonFeatureCatalog[theBolt->pathDF], true, false); } - if ((theBolt->flags & BF_FIERY) - && exposeTileToFire(x, y, true)) { + if ((theBolt->flags & BF_FIERY) && exposeTileToFire(x, y, true)) { if (lightingChanged) { *lightingChanged = true; @@ -4651,8 +4300,7 @@ boolean updateBolt(bolt *theBolt, creature *caster, short x, short y, } } - if ((theBolt->flags & BF_ELECTRIC) - && exposeTileToElectricity(x, y)) { + if ((theBolt->flags & BF_ELECTRIC) && exposeTileToElectricity(x, y)) { if (lightingChanged) { *lightingChanged = true; @@ -4675,13 +4323,11 @@ void detonateBolt(bolt *theBolt, creature *caster, short x, short y, boolean *au short i, x2, y2; creature *monst; - const fixpt POW_OBSTRUCTION[] = { - // 0.8^x, with x from 2 to 40: - 41943, 33554, 26843, 21474, 17179, 13743, 10995, 8796, 7036, 5629, 4503, 3602, - 2882, 2305, 1844, 1475, 1180, 944, 755, 604, 483, 386, 309, 247, 198, 158, 126, - 101, 81, 64, 51, 41, 33, 26, 21, 17, 13, 10, 8, 6, 5}; + const fixpt POW_OBSTRUCTION[] + = {// 0.8^x, with x from 2 to 40: + 41943, 33554, 26843, 21474, 17179, 13743, 10995, 8796, 7036, 5629, 4503, 3602, 2882, 2305, 1844, 1475, 1180, 944, 755, 604, 483, 386, 309, 247, 198, 158, 126, 101, 81, 64, 51, 41, 33, 26, 21, 17, 13, 10, 8, 6, 5}; - switch(theBolt->boltEffect) { + switch (theBolt->boltEffect) { case BE_OBSTRUCTION: feat = dungeonFeatureCatalog[DF_FORCEFIELD]; feat.probabilityDecrement = max(1, 75 * POW_OBSTRUCTION[min(40, theBolt->magnitude) - 2] / FP_FACTOR); @@ -4693,8 +4339,7 @@ void detonateBolt(bolt *theBolt, creature *caster, short x, short y, boolean *au case BE_CONJURATION: for (i = 0; i < (staffBladeCount(theBolt->magnitude * FP_FACTOR)); i++) { monst = generateMonster(MK_SPECTRAL_BLADE, true, false); - getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), x, y, true, - T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)) & ~T_SPONTANEOUSLY_IGNITES, HAS_PLAYER, + getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), x, y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)) & ~T_SPONTANEOUSLY_IGNITES, HAS_PLAYER, avoidedFlagsForMonster(&(monst->info)) & ~T_SPONTANEOUSLY_IGNITES, (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); monst->bookkeepingFlags |= (MB_FOLLOWER | MB_BOUND_TO_LEADER | MB_DOES_NOT_TRACK_LEADER); monst->bookkeepingFlags &= ~MB_JUST_SUMMONED; @@ -4702,11 +4347,11 @@ void detonateBolt(bolt *theBolt, creature *caster, short x, short y, boolean *au monst->creatureState = MONSTER_ALLY; monst->ticksUntilTurn = monst->info.attackSpeed + 1; // So they don't move before the player's next turn. pmapAt(monst->loc)->flags |= HAS_MONSTER; - //refreshDungeonCell(monst->loc.x, monst->loc.y); + // refreshDungeonCell(monst->loc.x, monst->loc.y); fadeInMonster(monst); } updateVision(true); - //refreshSideBar(-1, -1, false); + // refreshSideBar(-1, -1, false); monst = NULL; if (autoID) { *autoID = true; @@ -4717,7 +4362,7 @@ void detonateBolt(bolt *theBolt, creature *caster, short x, short y, boolean *au // We're blinking onto an area already occupied by a submerged monster. // Make sure we don't get the shooting monster by accident. caster->loc = INVALID_POS; // Will be set back to the destination in a moment. - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); findAlternativeHomeFor(monst, &x2, &y2, true); if (x2 >= 0) { // Found an alternative location. @@ -4808,15 +4453,15 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo numCells = -1; for (int i = 0; i < numCellsTmp; i++) { if (listOfCoordinatesTmp[i].x == originLoc.x && listOfCoordinatesTmp[i].y == originLoc.y) { - numCells = i+1; + numCells = i + 1; break; } } brogueAssert(numCells > -1); - for (int i = 0; i < numCells-1; i++) { - listOfCoordinates[i] = listOfCoordinatesTmp[numCells-2-i]; + for (int i = 0; i < numCells - 1; i++) { + listOfCoordinates[i] = listOfCoordinatesTmp[numCells - 2 - i]; } - listOfCoordinates[numCells-1] = targetLoc; + listOfCoordinates[numCells - 1] = targetLoc; } else { numCells = getLineCoordinates(listOfCoordinates, originLoc, targetLoc, (hideDetails ? &boltCatalog[BOLT_NONE] : theBolt)); } @@ -4833,11 +4478,10 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo if (theBolt->boltEffect == BE_BLINKING) { if (cellHasTerrainFlag(listOfCoordinates[0].x, listOfCoordinates[0].y, (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION)) - || ((pmapAt(listOfCoordinates[0])->flags & (HAS_PLAYER | HAS_MONSTER)) - && !(monsterAtLoc(listOfCoordinates[0])->bookkeepingFlags & MB_SUBMERGED))) { - // shooting blink point-blank into an obstruction does nothing. - return false; - } + || ((pmapAt(listOfCoordinates[0])->flags & (HAS_PLAYER | HAS_MONSTER)) && !(monsterAtLoc(listOfCoordinates[0])->bookkeepingFlags & MB_SUBMERGED))) { + // shooting blink point-blank into an obstruction does nothing. + return false; + } theBolt->foreColor = &black; theBolt->theChar = shootingMonst->info.displayChar; pmapAt(originLoc)->flags &= ~(HAS_PLAYER | HAS_MONSTER); @@ -4847,14 +4491,15 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo } if (boltColor) { - for (i=0; imagnitude * FP_FACTOR) * 4/3) * (initialBoltLength - i) / initialBoltLength / FP_FACTOR; + boltLightRadius = 50LL * ((3 * FP_FACTOR) + (theBolt->magnitude * FP_FACTOR) * 4 / 3) * (initialBoltLength - i) / initialBoltLength / FP_FACTOR; boltLights[i].lightRadius.lowerBound = boltLights[i].lightRadius.upperBound = boltLightRadius; - //boltLights[i].lightRadius.lowerBound = boltLights[i].lightRadius.upperBound = 50 * (3 + theBolt->magnitude * 1.33) * (initialBoltLength - i) / initialBoltLength; - //printf("\nStandard: %i, attempted new: %lli", boltLights[i].lightRadius.lowerBound, boltLightRadius); + // boltLights[i].lightRadius.lowerBound = boltLights[i].lightRadius.upperBound = 50 * (3 + + // theBolt->magnitude * 1.33) * (initialBoltLength - i) / initialBoltLength; printf("\nStandard: %i, + // attempted new: %lli", boltLights[i].lightRadius.lowerBound, boltLightRadius); } } @@ -4864,7 +4509,7 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo backUpLighting(lights); boltInView = true; - for (i=0; iflags & BF_NEVER_REFLECTS) - && projectileReflects(shootingMonst, monst) - && i < MAX_BOLT_LENGTH - max(DCOLS, DROWS)) { + if (monst && !(theBolt->flags & BF_NEVER_REFLECTS) && projectileReflects(shootingMonst, monst) && i < MAX_BOLT_LENGTH - max(DCOLS, DROWS)) { if (projectileReflects(shootingMonst, monst)) { // if it scores another reflection roll, reflect at caster numCells = reflectBolt(originLoc.x, originLoc.y, listOfCoordinates, i, !alreadyReflected); @@ -4887,16 +4529,10 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo if (boltInView) { monsterName(monstName, monst, true); - sprintf(buf, "%s deflect%s the %s", - monstName, - (monst == &player ? "" : "s"), - hideDetails ? "bolt" : theBolt->name); + sprintf(buf, "%s deflect%s the %s", monstName, (monst == &player ? "" : "s"), hideDetails ? "bolt" : theBolt->name); combatMessage(buf, 0); } - if (monst == &player - && rogue.armor - && rogue.armor->enchant2 == A_REFLECTION - && !(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED)) { + if (monst == &player && rogue.armor && rogue.armor->enchant2 == A_REFLECTION && !(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED)) { autoIdentify(rogue.armor); } @@ -4919,7 +4555,7 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo restoreLighting(lights); for (k = min(i, boltLength + 2); k >= 0; k--) { if (k < initialBoltLength) { - paintLight(&boltLights[k], listOfCoordinates[i-k].x, listOfCoordinates[i-k].y, false, false); + paintLight(&boltLights[k], listOfCoordinates[i - k].x, listOfCoordinates[i - k].y, false, false); } } } @@ -4927,8 +4563,8 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo updateFieldOfViewDisplay(false, true); // Now draw the bolt itself. for (k = min(i, boltLength + 2); k >= 0; k--) { - x2 = listOfCoordinates[i-k].x; - y2 = listOfCoordinates[i-k].y; + x2 = listOfCoordinates[i - k].x; + y2 = listOfCoordinates[i - k].y; if (playerCanSeeOrSense(x2, y2)) { if (!fastForward) { getCellAppearance(x2, y2, &theChar, &foreColor, &backColor); @@ -4945,18 +4581,14 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo theChar = theBolt->theChar; } } - if (displayChar - && theBolt->foreColor - && theBolt->theChar) { + if (displayChar && theBolt->foreColor && theBolt->theChar) { colorMultiplierFromDungeonLight(x2, y2, &multColor); applyColorMultiplier(&foreColor, &multColor); - plotCharWithColor(theChar, mapToWindow((pos){ x2, y2 }), &foreColor, &backColor); + plotCharWithColor(theChar, mapToWindow((pos){x2, y2}), &foreColor, &backColor); } else if (boltColor) { - plotCharWithColor(theChar, mapToWindow((pos){ x2, y2 }), &foreColor, &backColor); - } else if (k == 1 - && theBolt->foreColor - && theBolt->theChar) { + plotCharWithColor(theChar, mapToWindow((pos){x2, y2}), &foreColor, &backColor); + } else if (k == 1 && theBolt->foreColor && theBolt->theChar) { refreshDungeonCell(x2, y2); // Clean up the contrail so it doesn't leave a trail of characters. } @@ -4974,7 +4606,7 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo if (theBolt->boltEffect == BE_BLINKING) { theBolt->magnitude = (blinkDistance - i) / 2 + 1; boltLength = theBolt->magnitude * 5; - for (j=0; j= blinkDistance) { @@ -4983,18 +4615,17 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo } // Some bolts halt at the square before they hit something. - if ((theBolt->flags & BF_HALTS_BEFORE_OBSTRUCTION) - && i + 1 < numCells) { + if ((theBolt->flags & BF_HALTS_BEFORE_OBSTRUCTION) && i + 1 < numCells) { - x2 = listOfCoordinates[i+1].x; - y2 = listOfCoordinates[i+1].y; + x2 = listOfCoordinates[i + 1].x; + y2 = listOfCoordinates[i + 1].y; if (cellHasTerrainFlag(x2, y2, (T_OBSTRUCTS_VISION | T_OBSTRUCTS_PASSABILITY))) { break; } if (!(theBolt->flags & BF_PASSES_THRU_CREATURES)) { - monst = monsterAtLoc(listOfCoordinates[i+1]); + monst = monsterAtLoc(listOfCoordinates[i + 1]); if (monst && !(monst->bookkeepingFlags & MB_SUBMERGED)) { break; } @@ -5002,20 +4633,18 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo } // Tunnel if we hit a wall. - if (cellHasTerrainFlag(x, y, (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION)) - && theBolt->boltEffect == BE_TUNNELING - && tunnelize(x, y)) { + if (cellHasTerrainFlag(x, y, (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION)) && theBolt->boltEffect == BE_TUNNELING && tunnelize(x, y)) { updateVision(true); backUpLighting(lights); autoID = true; theBolt->magnitude--; boltLength = theBolt->magnitude * 5; - for (j=0; jmagnitude <= 0) { - refreshDungeonCell(listOfCoordinates[i-1].x, listOfCoordinates[i-1].y); + refreshDungeonCell(listOfCoordinates[i - 1].x, listOfCoordinates[i - 1].y); refreshDungeonCell(x, y); break; } @@ -5027,17 +4656,14 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo } // Does the bolt bounce before hitting a wall? - // Can happen with a cursed deflection ring or a reflective terrain target, or when shooting a tunneling bolt into an impregnable wall. - if (i + 1 < numCells - && !(theBolt->flags & BF_NEVER_REFLECTS)) { + // Can happen with a cursed deflection ring or a reflective terrain target, or when shooting a tunneling bolt + // into an impregnable wall. + if (i + 1 < numCells && !(theBolt->flags & BF_NEVER_REFLECTS)) { - x2 = listOfCoordinates[i+1].x; - y2 = listOfCoordinates[i+1].y; + x2 = listOfCoordinates[i + 1].x; + y2 = listOfCoordinates[i + 1].y; if (cellHasTerrainFlag(x2, y2, (T_OBSTRUCTS_VISION | T_OBSTRUCTS_PASSABILITY)) - && (projectileReflects(shootingMonst, NULL) - || cellHasTMFlag(x2, y2, TM_REFLECTS_BOLTS) - || (theBolt->boltEffect == BE_TUNNELING && (pmap[x2][y2].flags & IMPREGNABLE))) - && i < MAX_BOLT_LENGTH - max(DCOLS, DROWS)) { + && (projectileReflects(shootingMonst, NULL) || cellHasTMFlag(x2, y2, TM_REFLECTS_BOLTS) || (theBolt->boltEffect == BE_TUNNELING && (pmap[x2][y2].flags & IMPREGNABLE))) && i < MAX_BOLT_LENGTH - max(DCOLS, DROWS)) { sprintf(buf, "the bolt reflects off of %s", tileText(x2, y2)); if (projectileReflects(shootingMonst, NULL)) { @@ -5057,12 +4683,12 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo if (!fastForward) { refreshDungeonCell(x, y); if (i > 0) { - refreshDungeonCell(listOfCoordinates[i-1].x, listOfCoordinates[i-1].y); + refreshDungeonCell(listOfCoordinates[i - 1].x, listOfCoordinates[i - 1].y); } } if (pmap[x][y].flags & (HAS_MONSTER | HAS_PLAYER)) { - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); monsterName(monstName, monst, true); } else { monst = NULL; @@ -5077,7 +4703,7 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo if (boltLength > 0) { if (boltColor) { // j is where the front tip of the bolt would be if it hadn't collided at i - for (j=i; j < i + boltLength + 2; j++) { // j can imply a bolt tip position that is off the map + for (j = i; j < i + boltLength + 2; j++) { // j can imply a bolt tip position that is off the map // dynamic lighting if (boltInView) { @@ -5089,9 +4715,9 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo // boltLights[k].lightRadius.upperBound *= 2; // boltLights[k].lightColor = &boltImpactColor; - for (k = min(j, boltLength + 2); k >= j-i; k--) { + for (k = min(j, boltLength + 2); k >= j - i; k--) { if (k < initialBoltLength) { - paintLight(&boltLights[k], listOfCoordinates[j-k].x, listOfCoordinates[j-k].y, false, false); + paintLight(&boltLights[k], listOfCoordinates[j - k].x, listOfCoordinates[j - k].y, false, false); } } updateFieldOfViewDisplay(false, true); @@ -5101,10 +4727,10 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo // beam graphic // k iterates from the tail tip of the visible portion of the bolt to the head - for (k = min(j, boltLength + 2); k >= j-i; k--) { - if (playerCanSee(listOfCoordinates[j-k].x, listOfCoordinates[j-k].y)) { + for (k = min(j, boltLength + 2); k >= j - i; k--) { + if (playerCanSee(listOfCoordinates[j - k].x, listOfCoordinates[j - k].y)) { if (boltColor) { - hiliteCell(listOfCoordinates[j-k].x, listOfCoordinates[j-k].y, boltColor, max(0, 100 - k * 100 / (boltLength)), false); + hiliteCell(listOfCoordinates[j - k].x, listOfCoordinates[j - k].y, boltColor, max(0, 100 - k * 100 / (boltLength)), false); } boltInView = true; } @@ -5127,27 +4753,19 @@ boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, bo return autoID; } -// Relies on the sidebar entity list. If one is already selected, select the next qualifying. Otherwise, target the first qualifying. -boolean nextTargetAfter(short *returnX, - short *returnY, - short targetX, - short targetY, - boolean targetEnemies, - boolean targetAllies, - boolean targetItems, - boolean targetTerrain, - boolean requireOpenPath, - boolean reverseDirection) { +// Relies on the sidebar entity list. If one is already selected, select the next qualifying. Otherwise, target the +// first qualifying. +boolean nextTargetAfter(short *returnX, short *returnY, short targetX, short targetY, boolean targetEnemies, boolean targetAllies, boolean targetItems, boolean targetTerrain, boolean requireOpenPath, boolean reverseDirection) { short selectedIndex = 0; pos deduplicatedTargetList[ROWS]; int targetCount = 0; - for (int i=0; i= 0 && n < targetCount); - creature *const monst = monsterAtLoc((pos){ newX, newY }); + creature *const monst = monsterAtLoc((pos){newX, newY}); if (monst) { if (monstersAreEnemies(&player, monst)) { if (targetEnemies) { @@ -5205,7 +4821,7 @@ short hiliteTrajectory(const pos coordinateList[DCOLS], short numCells, boolean boolean isTunneling = theBolt && (theBolt->boltEffect == BE_TUNNELING); boolean passThroughMonsters = theBolt && (theBolt->flags & BF_PASSES_THRU_CREATURES); - for (i=0; ibookkeepingFlags & MB_SUBMERGED) - && !monsterIsHidden(monst, &player)) { + } else if (!passThroughMonsters && pmap[x][y].flags & (HAS_MONSTER) && (playerCanSee(x, y) || player.status[STATUS_TELEPATHIC])) { + monst = monsterAtLoc((pos){x, y}); + if (!(monst->bookkeepingFlags & MB_SUBMERGED) && !monsterIsHidden(monst, &player)) { i++; break; } } else if (cellHasTerrainFlag(x, y, T_IS_FLAMMABLE) && isFiery) { continue; - } else if (isTunneling && cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) && (pmap[x][y].flags & IMPREGNABLE) - || !isTunneling && cellHasTerrainFlag(x, y, (T_OBSTRUCTS_VISION | T_OBSTRUCTS_PASSABILITY))) { + } else if (isTunneling && cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) && (pmap[x][y].flags & IMPREGNABLE) || !isTunneling && cellHasTerrainFlag(x, y, (T_OBSTRUCTS_VISION | T_OBSTRUCTS_PASSABILITY))) { i++; break; } @@ -5241,15 +4854,7 @@ short hiliteTrajectory(const pos coordinateList[DCOLS], short numCells, boolean } // Event is optional. Returns true if the event should be executed by the parent function. -boolean moveCursor(boolean *targetConfirmed, - boolean *canceled, - boolean *tabKey, - pos *targetLoc, - rogueEvent *event, - buttonState *state, - boolean colorsDance, - boolean keysMoveCursor, - boolean targetCanLeaveMap) { +boolean moveCursor(boolean *targetConfirmed, boolean *canceled, boolean *tabKey, pos *targetLoc, rogueEvent *event, buttonState *state, boolean colorsDance, boolean keysMoveCursor, boolean targetCanLeaveMap) { signed long keystroke; short moveIncrement; short buttonInput; @@ -5269,7 +4874,7 @@ boolean moveCursor(boolean *targetConfirmed, oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; if (state) { // Also running a button loop. @@ -5296,11 +4901,7 @@ boolean moveCursor(boolean *targetConfirmed, restoreRNG; if (theEvent.eventType == MOUSE_UP || theEvent.eventType == MOUSE_ENTERED_CELL) { - if (theEvent.param1 >= 0 - && theEvent.param1 < mapToWindowX(0) - && theEvent.param2 >= 0 - && theEvent.param2 < ROWS - 1 - && isPosInMap(rogue.sidebarLocationList[theEvent.param2])) { + if (theEvent.param1 >= 0 && theEvent.param1 < mapToWindowX(0) && theEvent.param2 >= 0 && theEvent.param2 < ROWS - 1 && isPosInMap(rogue.sidebarLocationList[theEvent.param2])) { // If the cursor is on an entity in the sidebar. rogue.cursorLoc = rogue.sidebarLocationList[theEvent.param2]; @@ -5310,13 +4911,10 @@ boolean moveCursor(boolean *targetConfirmed, if (theEvent.eventType == MOUSE_UP) { *targetConfirmed = true; } - } else if (coordinatesAreInMap(windowToMapX(theEvent.param1), windowToMapY(theEvent.param2)) - || targetCanLeaveMap && theEvent.eventType != MOUSE_UP) { + } else if (coordinatesAreInMap(windowToMapX(theEvent.param1), windowToMapY(theEvent.param2)) || targetCanLeaveMap && theEvent.eventType != MOUSE_UP) { // If the cursor is in the map area, or is allowed to leave the map and it isn't a click. - if (theEvent.eventType == MOUSE_UP - && !theEvent.shiftKey - && (theEvent.controlKey || (rogue.cursorLoc.x == windowToMapX(theEvent.param1) && rogue.cursorLoc.y == windowToMapY(theEvent.param2)))) { + if (theEvent.eventType == MOUSE_UP && !theEvent.shiftKey && (theEvent.controlKey || (rogue.cursorLoc.x == windowToMapX(theEvent.param1) && rogue.cursorLoc.y == windowToMapY(theEvent.param2)))) { *targetConfirmed = true; } @@ -5329,9 +4927,9 @@ boolean moveCursor(boolean *targetConfirmed, } } else if (theEvent.eventType == KEYSTROKE) { keystroke = theEvent.param1; - moveIncrement = ( (theEvent.controlKey || theEvent.shiftKey) ? 5 : 1 ); + moveIncrement = ((theEvent.controlKey || theEvent.shiftKey) ? 5 : 1); stripShiftFromMovementKeystroke(&keystroke); - switch(keystroke) { + switch (keystroke) { case LEFT_ARROW: case LEFT_KEY: case NUMPAD_4: @@ -5417,13 +5015,12 @@ boolean moveCursor(boolean *targetConfirmed, again = true; } - if (sidebarHighlighted - && (!(pmapAt(rogue.cursorLoc)->flags & (HAS_PLAYER | HAS_MONSTER)) - || !canSeeMonster(monsterAtLoc(rogue.cursorLoc))) + if (sidebarHighlighted && (!(pmapAt(rogue.cursorLoc)->flags & (HAS_PLAYER | HAS_MONSTER)) || !canSeeMonster(monsterAtLoc(rogue.cursorLoc))) && (!(pmapAt(rogue.cursorLoc)->flags & HAS_ITEM) || !playerCanSeeOrSense(rogue.cursorLoc.x, rogue.cursorLoc.y)) && (!cellHasTMFlag(rogue.cursorLoc.x, rogue.cursorLoc.y, TM_LIST_IN_SIDEBAR) || !playerCanSeeOrSense(rogue.cursorLoc.x, rogue.cursorLoc.y))) { - // The sidebar is highlighted but the cursor is not on a visible item, monster or terrain. Un-highlight the sidebar. + // The sidebar is highlighted but the cursor is not on a visible item, monster or terrain. Un-highlight the + // sidebar. refreshSideBar(-1, -1, false); sidebarHighlighted = false; } @@ -5458,30 +5055,17 @@ pos pullMouseClickDuringPlayback(void) { brogueAssert(rogue.playbackMode); nextBrogueEvent(&theEvent, false, false, false); - return (pos){ - .x = windowToMapX(theEvent.param1), - .y = windowToMapY(theEvent.param2) - }; + return (pos){.x = windowToMapX(theEvent.param1), .y = windowToMapY(theEvent.param2)}; } // Returns whether monst is targetable with thrown items, staves, wands, etc. // i.e. would the player ever select it? static boolean creatureIsTargetable(creature *monst) { - return monst != NULL - && canSeeMonster(monst) - && monst->depth == rogue.depthLevel - && !(monst->bookkeepingFlags & MB_IS_DYING) - && openPathBetween(player.loc.x, player.loc.y, monst->loc.x, monst->loc.y); + return monst != NULL && canSeeMonster(monst) && monst->depth == rogue.depthLevel && !(monst->bookkeepingFlags & MB_IS_DYING) && openPathBetween(player.loc.x, player.loc.y, monst->loc.x, monst->loc.y); } // Return true if a target is chosen, or false if canceled. -boolean chooseTarget(pos *returnLoc, - short maxDistance, - boolean stopAtTarget, - boolean autoTarget, - boolean targetAllies, - const bolt *theBolt, - const color *trajectoryColor) { +boolean chooseTarget(pos *returnLoc, short maxDistance, boolean stopAtTarget, boolean autoTarget, boolean targetAllies, const bolt *theBolt, const color *trajectoryColor) { short numCells, i, distance, newX, newY; pos coordinates[DCOLS]; creature *monst; @@ -5501,7 +5085,7 @@ boolean chooseTarget(pos *returnLoc, oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; pos originLoc = player.loc; pos oldTargetLoc = player.loc; @@ -5511,9 +5095,9 @@ boolean chooseTarget(pos *returnLoc, if (creatureIsTargetable(rogue.lastTarget) && (targetAllies == (rogue.lastTarget->creatureState == MONSTER_ALLY))) { monst = rogue.lastTarget; } else { - //rogue.lastTarget = NULL; + // rogue.lastTarget = NULL; if (nextTargetAfter(&newX, &newY, targetLoc.x, targetLoc.y, !targetAllies, targetAllies, false, false, true, false)) { - targetLoc = (pos) { .x = newX, .y = newY }; + targetLoc = (pos){.x = newX, .y = newY}; } monst = monsterAtLoc(targetLoc); } @@ -5548,15 +5132,14 @@ boolean chooseTarget(pos *returnLoc, if (tabKey) { if (nextTargetAfter(&newX, &newY, targetLoc.x, targetLoc.y, !targetAllies, targetAllies, false, false, true, event.shiftKey)) { - targetLoc = (pos) { .x = newX, .y = newY }; + targetLoc = (pos){.x = newX, .y = newY}; } } monst = monsterAtLoc(targetLoc); if (monst != NULL && monst != &player && canSeeMonster(monst)) { focusedOnSomething = true; - } else if (playerCanSeeOrSense(targetLoc.x, targetLoc.y) - && (pmapAt(targetLoc)->flags & HAS_ITEM) || cellHasTMFlag(targetLoc.x, targetLoc.y, TM_LIST_IN_SIDEBAR)) { + } else if (playerCanSeeOrSense(targetLoc.x, targetLoc.y) && (pmapAt(targetLoc)->flags & HAS_ITEM) || cellHasTMFlag(targetLoc.x, targetLoc.y, TM_LIST_IN_SIDEBAR)) { focusedOnSomething = true; } else if (focusedOnSomething) { refreshSideBar(-1, -1, false); @@ -5580,7 +5163,7 @@ boolean chooseTarget(pos *returnLoc, } distance = hiliteTrajectory(coordinates, numCells, false, theBolt, &trajColor); cursorInTrajectory = false; - for (i=0; i 0)) { for (int i = 0; i < totalItemKinds; i++) { - if (!(theItemTable[i].identified) - && (theItemTable[i].magicPolarity == polarityConstraint || polarityConstraint == MAGIC_POLARITY_ANY)) { + if (!(theItemTable[i].identified) && (theItemTable[i].magicPolarity == polarityConstraint || polarityConstraint == MAGIC_POLARITY_ANY)) { if (lastItemKind != -1) { return -1; // At least two unidentified items remain. } @@ -5716,8 +5298,7 @@ static int magicPolarityRevealedItemKindCount(enum itemCategory category, int po if (theItemTable && (totalItemKinds > 0) && polarityConstraint) { kindCount = 0; for (int i = 0; i < totalItemKinds; i++) { - if (theItemTable[i].magicPolarity == polarityConstraint && - (theItemTable[i].identified || theItemTable[i].magicPolarityRevealed)) { + if (theItemTable[i].magicPolarity == polarityConstraint && (theItemTable[i].identified || theItemTable[i].magicPolarityRevealed)) { kindCount += 1; } } @@ -5765,7 +5346,7 @@ static void tryIdentifyLastItemKinds(enum itemCategory category) { categoryCount = NUMBER_ITEM_CATEGORIES; } - for (int i=0; icategory & RING) - && theItem->enchant1 <= 0) { + if ((theItem->category & RING) && theItem->enchant1 <= 0) { theItem->flags |= ITEM_IDENTIFIED; } - if ((theItem->category & WAND) - && theTable[theItem->kind].range.lowerBound == theTable[theItem->kind].range.upperBound) { + if ((theItem->category & WAND) && theTable[theItem->kind].range.lowerBound == theTable[theItem->kind].range.upperBound) { theItem->flags |= ITEM_IDENTIFIED; } @@ -5825,23 +5404,18 @@ void autoIdentify(item *theItem) { short quantityBackup; char buf[COLS * 3], oldName[COLS * 3], newName[COLS * 3]; - if (tableForItemCategory(theItem->category) - && !tableForItemCategory(theItem->category)[theItem->kind].identified) { + if (tableForItemCategory(theItem->category) && !tableForItemCategory(theItem->category)[theItem->kind].identified) { identifyItemKind(theItem); quantityBackup = theItem->quantity; theItem->quantity = 1; itemName(theItem, newName, false, true, NULL); theItem->quantity = quantityBackup; - sprintf(buf, "(It must %s %s.)", - ((theItem->category & (POTION | SCROLL)) ? "have been" : "be"), - newName); + sprintf(buf, "(It must %s %s.)", ((theItem->category & (POTION | SCROLL)) ? "have been" : "be"), newName); messageWithColor(buf, &itemMessageColor, 0); } - if ((theItem->category & (WEAPON | ARMOR)) - && (theItem->flags & ITEM_RUNIC) - && !(theItem->flags & ITEM_RUNIC_IDENTIFIED)) { + if ((theItem->category & (WEAPON | ARMOR)) && (theItem->flags & ITEM_RUNIC) && !(theItem->flags & ITEM_RUNIC_IDENTIFIED)) { itemName(theItem, oldName, false, false, NULL); theItem->flags |= (ITEM_RUNIC_IDENTIFIED | ITEM_RUNIC_HINTED); @@ -5869,11 +5443,7 @@ boolean hitMonsterWithProjectileWeapon(creature *thrower, creature *monst, item monst->status[STATUS_ENTRANCED] = 0; - if (monst != &player - && monst->creatureMode != MODE_PERM_FLEEING - && (monst->creatureState != MONSTER_FLEEING || monst->status[STATUS_MAGICAL_FEAR]) - && !(monst->bookkeepingFlags & MB_CAPTIVE) - && monst->creatureState != MONSTER_ALLY) { + if (monst != &player && monst->creatureMode != MODE_PERM_FLEEING && (monst->creatureState != MONSTER_FLEEING || monst->status[STATUS_MAGICAL_FEAR]) && !(monst->bookkeepingFlags & MB_CAPTIVE) && monst->creatureState != MONSTER_ALLY) { monst->creatureState = MONSTER_TRACKING_SCENT; if (monst->status[STATUS_MAGICAL_FEAR]) { @@ -5895,18 +5465,14 @@ boolean hitMonsterWithProjectileWeapon(creature *thrower, creature *monst, item } if (thrownWeaponHit) { - damage = monst->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE) ? 0 : - (randClump(theItem->damage) * damageFraction(netEnchant(theItem)) / FP_FACTOR); + damage = monst->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE) ? 0 : (randClump(theItem->damage) * damageFraction(netEnchant(theItem)) / FP_FACTOR); if (monst == &player) { applyArmorRunicEffect(armorRunicString, thrower, &damage, false); } if (inflictDamage(thrower, monst, damage, &red, false)) { // monster killed - sprintf(buf, "the %s %s %s.", - theItemName, - (monst->info.flags & MONST_INANIMATE) ? "destroyed" : "killed", - targetName); + sprintf(buf, "the %s %s %s.", theItemName, (monst->info.flags & MONST_INANIMATE) ? "destroyed" : "killed", targetName); messageWithColor(buf, messageColorFromVictim(monst), 0); killCreature(monst, false); } else { @@ -5932,7 +5498,7 @@ boolean hitMonsterWithProjectileWeapon(creature *thrower, creature *monst, item void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistance) { short i, numCells; creature *monst = NULL; - char buf[COLS*3], buf2[COLS*3], buf3[COLS*3]; + char buf[COLS * 3], buf2[COLS * 3], buf3[COLS * 3]; enum displayGlyph displayChar; color foreColor, backColor, multColor; boolean hitSomethingSolid = false, fastForward = false; @@ -5944,14 +5510,14 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc short x = originLoc.x; short y = originLoc.y; - // Using BOLT_NONE for throws because all flags are off, which means we'll try to avoid all obstacles in front of the target + // Using BOLT_NONE for throws because all flags are off, which means we'll try to avoid all obstacles in front of + // the target pos listOfCoordinates[MAX_BOLT_LENGTH]; numCells = getLineCoordinates(listOfCoordinates, originLoc, targetLoc, &boltCatalog[BOLT_NONE]); thrower->ticksUntilTurn = thrower->attackSpeed; - if (thrower != &player - && (pmapAt(originLoc)->flags & IN_FIELD_OF_VIEW)) { + if (thrower != &player && (pmapAt(originLoc)->flags & IN_FIELD_OF_VIEW)) { monsterName(buf2, thrower, true); itemName(theItem, buf3, false, true, NULL); @@ -5959,29 +5525,29 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc message(buf, 0); } - for (i=0; ibookkeepingFlags & MB_SUBMERGED)) { -// if (projectileReflects(thrower, monst) && i < DCOLS*2) { -// if (projectileReflects(thrower, monst)) { // if it scores another reflection roll, reflect at caster -// numCells = reflectBolt(originLoc[0], originLoc.y, listOfCoordinates, i, true); -// } else { -// numCells = reflectBolt(-1, -1, listOfCoordinates, i, false); // otherwise reflect randomly -// } -// -// monsterName(buf2, monst, true); -// itemName(theItem, buf3, false, false, NULL); -// sprintf(buf, "%s deflect%s the %s", buf2, (monst == &player ? "" : "s"), buf3); -// combatMessage(buf, 0); -// continue; -// } - if ((theItem->category & WEAPON) - && theItem->kind != INCENDIARY_DART - && hitMonsterWithProjectileWeapon(thrower, monst, theItem)) { + // if (projectileReflects(thrower, monst) && i < DCOLS*2) { + // if (projectileReflects(thrower, monst)) { // if it scores another reflection roll, + // reflect at caster + // numCells = reflectBolt(originLoc[0], originLoc.y, listOfCoordinates, i, true); + // } else { + // numCells = reflectBolt(-1, -1, listOfCoordinates, i, false); // otherwise reflect + // randomly + // } + // + // monsterName(buf2, monst, true); + // itemName(theItem, buf3, false, false, NULL); + // sprintf(buf, "%s deflect%s the %s", buf2, (monst == &player ? "" : "s"), buf3); + // combatMessage(buf, 0); + // continue; + // } + if ((theItem->category & WEAPON) && theItem->kind != INCENDIARY_DART && hitMonsterWithProjectileWeapon(thrower, monst, theItem)) { deleteItem(theItem); return; } @@ -5991,13 +5557,10 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc // We hit something! if (cellHasTerrainFlag(x, y, (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION))) { - if ((theItem->category & WEAPON) - && (theItem->kind == INCENDIARY_DART) - && (cellHasTerrainFlag(x, y, T_IS_FLAMMABLE) || (pmap[x][y].flags & (HAS_MONSTER | HAS_PLAYER)))) { - // Incendiary darts thrown at flammable obstructions (foliage, wooden barricades, doors) will hit the obstruction - // instead of bursting a cell earlier. - } else if (cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) - && cellHasTMFlag(x, y, TM_PROMOTES_ON_PLAYER_ENTRY) + if ((theItem->category & WEAPON) && (theItem->kind == INCENDIARY_DART) && (cellHasTerrainFlag(x, y, T_IS_FLAMMABLE) || (pmap[x][y].flags & (HAS_MONSTER | HAS_PLAYER)))) { + // Incendiary darts thrown at flammable obstructions (foliage, wooden barricades, doors) will hit the + // obstruction instead of bursting a cell earlier. + } else if (cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) && cellHasTMFlag(x, y, TM_PROMOTES_ON_PLAYER_ENTRY) && tileCatalog[pmap[x][y].layers[layerWithTMFlag(x, y, TM_PROMOTES_ON_PLAYER_ENTRY)]].flags & T_OBSTRUCTS_PASSABILITY) { layer = layerWithTMFlag(x, y, TM_PROMOTES_ON_PLAYER_ENTRY); if (tileCatalog[pmap[x][y].layers[layer]].flags & T_OBSTRUCTS_PASSABILITY) { @@ -6027,7 +5590,7 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc } else { // clairvoyant visible applyColorMultiplier(&foreColor, &clairvoyanceColor); } - plotCharWithColor(theItem->displayChar, mapToWindow((pos){ x, y }), &foreColor, &backColor); + plotCharWithColor(theItem->displayChar, mapToWindow((pos){x, y}), &foreColor, &backColor); if (!fastForward) { fastForward = rogue.playbackFastForward || pauseAnimation(25); @@ -6042,9 +5605,7 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc } if ((theItem->category & POTION) && (hitSomethingSolid || !cellHasTerrainFlag(x, y, T_AUTO_DESCENT))) { - if (theItem->kind == POTION_CONFUSION || theItem->kind == POTION_POISON - || theItem->kind == POTION_PARALYSIS || theItem->kind == POTION_INCINERATION - || theItem->kind == POTION_DARKNESS || theItem->kind == POTION_LICHEN + if (theItem->kind == POTION_CONFUSION || theItem->kind == POTION_POISON || theItem->kind == POTION_PARALYSIS || theItem->kind == POTION_INCINERATION || theItem->kind == POTION_DARKNESS || theItem->kind == POTION_LICHEN || theItem->kind == POTION_DESCENT) { switch (theItem->kind) { case POTION_POISON: @@ -6088,7 +5649,7 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc refreshDungeonCell(x, y); - //if (pmap[x][y].flags & (HAS_MONSTER | HAS_PLAYER)) { + // if (pmap[x][y].flags & (HAS_MONSTER | HAS_PLAYER)) { // monst = monsterAtLoc((pos){ x, y }); // applyInstantTileEffectsToCreature(monst); //} @@ -6100,13 +5661,11 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc } else { strcpy(buf2, "on"); } - sprintf(buf, "the flask shatters and %s liquid splashes harmlessly %s %s.", - potionTable[theItem->kind].flavor, buf2, tileText(x, y)); + sprintf(buf, "the flask shatters and %s liquid splashes harmlessly %s %s.", potionTable[theItem->kind].flavor, buf2, tileText(x, y)); message(buf, 0); // hallucination is the only malevolent potion that splashes harmlessly when thrown if (theItem->kind == POTION_HALLUCINATION) { - if (theItem->flags & ITEM_MAGIC_DETECTED - || (magicPolarityRevealedItemKindCount(theItem->category, 1) == gameConst->numberGoodPotionKinds)) { + if (theItem->flags & ITEM_MAGIC_DETECTED || (magicPolarityRevealedItemKindCount(theItem->category, 1) == gameConst->numberGoodPotionKinds)) { autoIdentify(theItem); } } @@ -6117,7 +5676,7 @@ void throwItem(item *theItem, creature *thrower, pos targetLoc, short maxDistanc if ((theItem->category & WEAPON) && theItem->kind == INCENDIARY_DART) { spawnDungeonFeature(x, y, &dungeonFeatureCatalog[DF_DART_EXPLOSION], true, false); if (pmap[x][y].flags & (HAS_MONSTER | HAS_PLAYER)) { - exposeCreatureToFire(monsterAtLoc((pos){ x, y })); + exposeCreatureToFire(monsterAtLoc((pos){x, y})); } deleteItem(theItem); return; @@ -6146,8 +5705,7 @@ void throwCommand(item *theItem, boolean autoThrow) { // Else ask ITEM // if (theItem == NULL) { - theItem = promptForItemOfType((ALL_ITEMS), 0, 0, - KEYBOARD_LABELS ? "Throw what? (a-z, shift for more info; or to cancel)" : "Throw what?", true); + theItem = promptForItemOfType((ALL_ITEMS), 0, 0, KEYBOARD_LABELS ? "Throw what? (a-z, shift for more info; or to cancel)" : "Throw what?", true); } if (theItem == NULL) { return; @@ -6167,8 +5725,7 @@ void throwCommand(item *theItem, boolean autoThrow) { // // If special item (not throw item) // -> Confirm before throw - if (((theItem->flags & ITEM_EQUIPPED) || theItem->timesEnchanted > 0) - && theItem->quantity <= 1) { + if (((theItem->flags & ITEM_EQUIPPED) || theItem->timesEnchanted > 0) && theItem->quantity <= 1) { sprintf(buf, "Are you sure you want to throw your %s?", theName); if (!confirm(buf, false)) { @@ -6184,9 +5741,7 @@ void throwCommand(item *theItem, boolean autoThrow) { // // Ask location to throw // - sprintf(buf, "Throw %s %s where? (, mouse, or )", - (theItem->quantity > 1 ? "a" : "your"), - theName); + sprintf(buf, "Throw %s %s where? (, mouse, or )", (theItem->quantity > 1 ? "a" : "your"), theName); temporaryMessage(buf, REFRESH_SIDEBAR); maxDistance = (12 + 2 * max(rogue.strength - player.weaknessAmount - 12, 2)); @@ -6199,8 +5754,7 @@ void throwCommand(item *theItem, boolean autoThrow) { } break; case POTION: - if ((theItem->flags & ITEM_MAGIC_DETECTED || potionTable[theItem->kind].identified) - && itemMagicPolarity(theItem) == -1) { + if ((theItem->flags & ITEM_MAGIC_DETECTED || potionTable[theItem->kind].identified) && itemMagicPolarity(theItem) == -1) { autoTarget = true; } break; @@ -6225,10 +5779,10 @@ void throwCommand(item *theItem, boolean autoThrow) { confirmMessages(); - thrownItem = generateItem(ALL_ITEMS, -1); // generate item object in memory - *thrownItem = *theItem; // clone the item - thrownItem->flags &= ~ITEM_EQUIPPED; // item not equiped - thrownItem->quantity = 1; // item thrown, so quantity == 1 + thrownItem = generateItem(ALL_ITEMS, -1); // generate item object in memory + *thrownItem = *theItem; // clone the item + thrownItem->flags &= ~ITEM_EQUIPPED; // item not equiped + thrownItem->quantity = 1; // item thrown, so quantity == 1 itemName(thrownItem, theName, false, false, NULL); // update name of the thrown item @@ -6261,8 +5815,7 @@ void relabel(item *theItem) { return; } if (theItem == NULL) { - theItem = promptForItemOfType((ALL_ITEMS), 0, 0, - KEYBOARD_LABELS ? "Relabel what? (a-z, shift for more info; or to cancel)" : "Relabel what?", true); + theItem = promptForItemOfType((ALL_ITEMS), 0, 0, KEYBOARD_LABELS ? "Relabel what? (a-z, shift for more info; or to cancel)" : "Relabel what?", true); } if (theItem == NULL) { return; @@ -6297,10 +5850,7 @@ void relabel(item *theItem) { messageWithColor(buf, &itemMessageColor, 0); } else { itemName(theItem, theName, true, true, NULL); - sprintf(buf, "%s %s already labeled (%c).", - theName, - theItem->quantity == 1 ? "is" : "are", - theItem->inventoryLetter); + sprintf(buf, "%s %s already labeled (%c).", theName, theItem->quantity == 1 ? "is" : "are", theItem->inventoryLetter); messageWithColor(buf, &itemMessageColor, 0); } } @@ -6347,8 +5897,7 @@ boolean playerCancelsBlinking(const pos originLoc, const pos targetLoc, const sh return false; } - if (player.status[STATUS_IMMUNE_TO_FIRE] - || player.status[STATUS_LEVITATING]) { + if (player.status[STATUS_IMMUNE_TO_FIRE] || player.status[STATUS_LEVITATING]) { return false; } @@ -6356,10 +5905,7 @@ boolean playerCancelsBlinking(const pos originLoc, const pos targetLoc, const sh getImpactLoc(&impactLoc, originLoc, targetLoc, maxDistance > 0 ? maxDistance : DCOLS, true, &boltCatalog[BOLT_BLINKING]); getLocationFlags(impactLoc.x, impactLoc.y, &tFlags, &tmFlags, NULL, true); if (maxDistance > 0) { - if ((pmapAt(impactLoc)->flags & DISCOVERED) - && (tFlags & T_LAVA_INSTA_DEATH) - && !(tFlags & (T_ENTANGLES | T_AUTO_DESCENT)) - && !(tmFlags & TM_EXTINGUISHES_FIRE)) { + if ((pmapAt(impactLoc)->flags & DISCOVERED) && (tFlags & T_LAVA_INSTA_DEATH) && !(tFlags & (T_ENTANGLES | T_AUTO_DESCENT)) && !(tmFlags & TM_EXTINGUISHES_FIRE)) { certainDeath = possibleDeath = true; } @@ -6372,9 +5918,7 @@ boolean playerCancelsBlinking(const pos originLoc, const pos targetLoc, const sh y = coordinates[i].y; if (pmap[x][y].flags & DISCOVERED) { getLocationFlags(x, y, &tFlags, NULL, NULL, true); - if ((tFlags & T_LAVA_INSTA_DEATH) - && !(tFlags & (T_ENTANGLES | T_AUTO_DESCENT)) - && !(tmFlags & TM_EXTINGUISHES_FIRE)) { + if ((tFlags & T_LAVA_INSTA_DEATH) && !(tFlags & (T_ENTANGLES | T_AUTO_DESCENT)) && !(tmFlags & TM_EXTINGUISHES_FIRE)) { possibleDeath = true; } else if (i >= staffBlinkDistance(2 * FP_FACTOR) - 1) { @@ -6391,8 +5935,7 @@ boolean playerCancelsBlinking(const pos originLoc, const pos targetLoc, const sh message("that would be certain death!", 0); return true; } - if (possibleDeath - && !confirm("Blink across lava with unknown range?", false)) { + if (possibleDeath && !confirm("Blink across lava with unknown range?", false)) { return true; } return false; @@ -6426,8 +5969,7 @@ boolean useStaffOrWand(item *theItem, boolean *commandsRecorded) { theBolt.magnitude = theItem->enchant1; } - if ((theItem->category & STAFF) && theItem->kind == STAFF_BLINKING - && theItem->flags & (ITEM_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN)) { + if ((theItem->category & STAFF) && theItem->kind == STAFF_BLINKING && theItem->flags & (ITEM_IDENTIFIED | ITEM_MAX_CHARGES_KNOWN)) { maxDistance = staffBlinkDistance(netEnchant(theItem)); } else { @@ -6447,8 +5989,7 @@ boolean useStaffOrWand(item *theItem, boolean *commandsRecorded) { autoTarget = true; targetAllies = false; } - boltKnown = (((theItem->category & WAND) && wandTable[theItem->kind].identified) - || ((theItem->category & STAFF) && staffTable[theItem->kind].identified)); + boltKnown = (((theItem->category & WAND) && wandTable[theItem->kind].identified) || ((theItem->category & STAFF) && staffTable[theItem->kind].identified)); if (!boltKnown) { trajectoryHiliteColor = gray; } else if (theBolt.backColor == NULL) { @@ -6459,12 +6000,8 @@ boolean useStaffOrWand(item *theItem, boolean *commandsRecorded) { pos originLoc = player.loc; pos zapTarget; - confirmedTarget = chooseTarget(&zapTarget, maxDistance, false, autoTarget, - targetAllies, (boltKnown ? &theBolt : &boltCatalog[BOLT_NONE]), &trajectoryHiliteColor); - if (confirmedTarget - && boltKnown - && theBolt.boltEffect == BE_BLINKING - && playerCancelsBlinking(originLoc, zapTarget, maxDistance)) { + confirmedTarget = chooseTarget(&zapTarget, maxDistance, false, autoTarget, targetAllies, (boltKnown ? &theBolt : &boltCatalog[BOLT_NONE]), &trajectoryHiliteColor); + if (confirmedTarget && boltKnown && theBolt.boltEffect == BE_BLINKING && playerCancelsBlinking(originLoc, zapTarget, maxDistance)) { confirmedTarget = false; } @@ -6481,9 +6018,8 @@ boolean useStaffOrWand(item *theItem, boolean *commandsRecorded) { rogue.featRecord[FEAT_PURE_WARRIOR] = false; if (theItem->charges > 0) { - autoID = zap(originLoc, zapTarget, - &theBolt, - !boltKnown, // hide bolt details + autoID = zap(originLoc, zapTarget, &theBolt, + !boltKnown, // hide bolt details false); if (autoID) { if (!tableForItemCategory(theItem->category)[theItem->kind].identified) { @@ -6519,9 +6055,8 @@ void summonGuardian(item *theItem) { creature *monst; monst = generateMonster(MK_CHARM_GUARDIAN, false, false); - getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), x, y, true, - T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)) & ~T_SPONTANEOUSLY_IGNITES, HAS_PLAYER, - avoidedFlagsForMonster(&(monst->info)) & ~T_SPONTANEOUSLY_IGNITES, (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); + getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), x, y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)) & ~T_SPONTANEOUSLY_IGNITES, HAS_PLAYER, avoidedFlagsForMonster(&(monst->info)) & ~T_SPONTANEOUSLY_IGNITES, + (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); monst->bookkeepingFlags |= (MB_FOLLOWER | MB_BOUND_TO_LEADER | MB_DOES_NOT_TRACK_LEADER); monst->bookkeepingFlags &= ~MB_JUST_SUMMONED; monst->leader = &player; @@ -6609,30 +6144,20 @@ void apply(item *theItem, boolean recordCommands) { revealItemType = false; if (!theItem) { - theItem = promptForItemOfType((SCROLL|FOOD|POTION|STAFF|WAND|CHARM), 0, 0, - KEYBOARD_LABELS ? "Apply what? (a-z, shift for more info; or to cancel)" : "Apply what?", - true); + theItem = promptForItemOfType((SCROLL | FOOD | POTION | STAFF | WAND | CHARM), 0, 0, KEYBOARD_LABELS ? "Apply what? (a-z, shift for more info; or to cancel)" : "Apply what?", true); } if (theItem == NULL) { return; } - if ((theItem->category == SCROLL || theItem->category == POTION) - && magicCharDiscoverySuffix(theItem->category, theItem->kind) == -1 + if ((theItem->category == SCROLL || theItem->category == POTION) && magicCharDiscoverySuffix(theItem->category, theItem->kind) == -1 && ((theItem->flags & ITEM_MAGIC_DETECTED) || tableForItemCategory(theItem->category)[theItem->kind].identified)) { if (tableForItemCategory(theItem->category)[theItem->kind].identified) { - sprintf(buf, - "Really %s a %s of %s?", - theItem->category == SCROLL ? "read" : "drink", - theItem->category == SCROLL ? "scroll" : "potion", - tableForItemCategory(theItem->category)[theItem->kind].name); + sprintf(buf, "Really %s a %s of %s?", theItem->category == SCROLL ? "read" : "drink", theItem->category == SCROLL ? "scroll" : "potion", tableForItemCategory(theItem->category)[theItem->kind].name); } else { - sprintf(buf, - "Really %s a cursed %s?", - theItem->category == SCROLL ? "read" : "drink", - theItem->category == SCROLL ? "scroll" : "potion"); + sprintf(buf, "Really %s a cursed %s?", theItem->category == SCROLL ? "read" : "drink", theItem->category == SCROLL ? "scroll" : "potion"); } if (!confirm(buf, false)) { return; @@ -6644,8 +6169,7 @@ void apply(item *theItem, boolean recordCommands) { switch (theItem->category) { case FOOD: if (STOMACH_SIZE - player.status[STATUS_NUTRITION] < foodTable[theItem->kind].power) { // Not hungry enough. - sprintf(buf, "You're not hungry enough to fully enjoy the %s. Eat it anyway?", - (theItem->kind == RATION ? "food" : "mango")); + sprintf(buf, "You're not hungry enough to fully enjoy the %s. Eat it anyway?", (theItem->kind == RATION ? "food" : "mango")); if (!confirm(buf, false)) { return; } @@ -6675,9 +6199,7 @@ void apply(item *theItem, boolean recordCommands) { recordKeystrokeSequence(command); commandsRecorded = true; // have to record in case further keystrokes are necessary (e.g. enchant scroll) } - if (!scrollTable[theItem->kind].identified - && theItem->kind != SCROLL_ENCHANTING - && theItem->kind != SCROLL_IDENTIFY) { + if (!scrollTable[theItem->kind].identified && theItem->kind != SCROLL_ENCHANTING && theItem->kind != SCROLL_IDENTIFY) { revealItemType = true; } @@ -6775,8 +6297,7 @@ short lotteryDraw(short *frequencies, short itemCount) { short chooseVorpalEnemy() { short i, frequencies[MONSTER_CLASS_COUNT]; for (i = 0; i < MONSTER_CLASS_COUNT; i++) { - if (monsterClassCatalog[i].maxDepth <= 0 - || rogue.depthLevel <= monsterClassCatalog[i].maxDepth) { + if (monsterClassCatalog[i].maxDepth <= 0 || rogue.depthLevel <= monsterClassCatalog[i].maxDepth) { frequencies[i] = monsterClassCatalog[i].frequency; } else { @@ -6809,14 +6330,10 @@ void updateIdentifiableItem(item *theItem) { theItem->flags &= ~ITEM_CAN_BE_IDENTIFIED; } else if ((theItem->category & POTION) && potionTable[theItem->kind].identified) { theItem->flags &= ~ITEM_CAN_BE_IDENTIFIED; - } else if ((theItem->category & (RING | STAFF | WAND)) - && (theItem->flags & ITEM_IDENTIFIED) - && tableForItemCategory(theItem->category)[theItem->kind].identified) { + } else if ((theItem->category & (RING | STAFF | WAND)) && (theItem->flags & ITEM_IDENTIFIED) && tableForItemCategory(theItem->category)[theItem->kind].identified) { theItem->flags &= ~ITEM_CAN_BE_IDENTIFIED; - } else if ((theItem->category & (WEAPON | ARMOR)) - && (theItem->flags & ITEM_IDENTIFIED) - && (!(theItem->flags & ITEM_RUNIC) || (theItem->flags & ITEM_RUNIC_IDENTIFIED))) { + } else if ((theItem->category & (WEAPON | ARMOR)) && (theItem->flags & ITEM_IDENTIFIED) && (!(theItem->flags & ITEM_RUNIC) || (theItem->flags & ITEM_RUNIC_IDENTIFIED))) { theItem->flags &= ~ITEM_CAN_BE_IDENTIFIED; } else if (theItem->category & NEVER_IDENTIFIABLE) { @@ -6864,9 +6381,7 @@ void readScroll(item *theItem) { break; } do { - theItem = promptForItemOfType((ALL_ITEMS), ITEM_CAN_BE_IDENTIFIED, 0, - KEYBOARD_LABELS ? "Identify what? (a-z; shift for more info)" : "Identify what?", - false); + theItem = promptForItemOfType((ALL_ITEMS), ITEM_CAN_BE_IDENTIFIED, 0, KEYBOARD_LABELS ? "Identify what? (a-z; shift for more info)" : "Identify what?", false); if (rogue.gameHasEnded) { return; } @@ -6909,9 +6424,7 @@ void readScroll(item *theItem) { break; } do { - theItem = promptForItemOfType((WEAPON | ARMOR | RING | STAFF | WAND | CHARM), 0, 0, - KEYBOARD_LABELS ? "Enchant what? (a-z; shift for more info)" : "Enchant what?", - false); + theItem = promptForItemOfType((WEAPON | ARMOR | RING | STAFF | WAND | CHARM), 0, 0, KEYBOARD_LABELS ? "Enchant what? (a-z; shift for more info)" : "Enchant what?", false); confirmMessages(); if (theItem == NULL || !(theItem->category & (WEAPON | ARMOR | RING | STAFF | WAND | CHARM))) { message("Can't enchant that.", REQUIRE_ACKNOWLEDGMENT); @@ -6962,8 +6475,7 @@ void readScroll(item *theItem) { break; } theItem->timesEnchanted += enchantMagnitude(); - if ((theItem->category & (WEAPON | ARMOR | STAFF | RING | CHARM)) - && theItem->enchant1 >= 16) { + if ((theItem->category & (WEAPON | ARMOR | STAFF | RING | CHARM)) && theItem->enchant1 >= 16) { rogue.featRecord[FEAT_SPECIALIST] = true; } @@ -7027,8 +6539,8 @@ void readScroll(item *theItem) { case SCROLL_MAGIC_MAPPING: confirmMessages(); messageWithColor("this scroll has a map on it!", &itemMessageColor, 0); - for (i=0; ikind].magicPolarityRevealed = true; } theItem->flags |= ITEM_MAGIC_DETECTED; - if ((theItem->category & (WEAPON | ARMOR)) - && theItem->enchant1 == 0 - && !(theItem->flags & ITEM_RUNIC)) { + if ((theItem->category & (WEAPON | ARMOR)) && theItem->enchant1 == 0 && !(theItem->flags & ITEM_RUNIC)) { identify(theItem); } @@ -7126,9 +6635,7 @@ void drinkPotion(item *theItem) { switch (theItem->kind) { case POTION_LIFE: magnitude = randClump(potionTable.range); - sprintf(buf, "%syour maximum health increases by %i%%.", - ((player.currentHP < player.info.maxHP) ? "you heal completely and " : ""), - (player.info.maxHP + magnitude) * 100 / player.info.maxHP - 100); + sprintf(buf, "%syour maximum health increases by %i%%.", ((player.currentHP < player.info.maxHP) ? "you heal completely and " : ""), (player.info.maxHP + magnitude) * 100 / player.info.maxHP - 100); player.info.maxHP += magnitude; heal(&player, 100, true); @@ -7141,7 +6648,7 @@ void drinkPotion(item *theItem) { message("colors are everywhere! The walls are singing!", 0); break; case POTION_INCINERATION: - //colorFlash(&darkOrange, 0, IN_FIELD_OF_VIEW, 4, 4, player.loc.x, player.loc.y); + // colorFlash(&darkOrange, 0, IN_FIELD_OF_VIEW, 4, 4, player.loc.x, player.loc.y); message("as you uncork the flask, it explodes in flame!", 0); spawnDungeonFeature(player.loc.x, player.loc.y, &dungeonFeatureCatalog[DF_INCINERATION_POTION], true, false); exposeCreatureToFire(&player); @@ -7362,9 +6869,7 @@ void unequip(item *theItem) { command[0] = UNEQUIP_KEY; if (theItem == NULL) { - theItem = promptForItemOfType(ALL_ITEMS, ITEM_EQUIPPED, 0, - KEYBOARD_LABELS ? "Remove (unequip) what? (a-z or to cancel)" : "Remove (unequip) what?", - true); + theItem = promptForItemOfType(ALL_ITEMS, ITEM_EQUIPPED, 0, KEYBOARD_LABELS ? "Remove (unequip) what? (a-z or to cancel)" : "Remove (unequip) what?", true); } if (theItem == NULL) { return; @@ -7375,9 +6880,7 @@ void unequip(item *theItem) { if (!(theItem->flags & ITEM_EQUIPPED)) { itemName(theItem, buf2, false, false, NULL); - sprintf(buf, "your %s %s not equipped.", - buf2, - theItem->quantity == 1 ? "was" : "were"); + sprintf(buf, "your %s %s not equipped.", buf2, theItem->quantity == 1 ? "was" : "were"); confirmMessages(); messageWithColor(buf, &itemMessageColor, 0); return; @@ -7410,9 +6913,7 @@ void drop(item *theItem) { command[0] = DROP_KEY; if (theItem == NULL) { - theItem = promptForItemOfType(ALL_ITEMS, 0, 0, - KEYBOARD_LABELS ? "Drop what? (a-z, shift for more info; or to cancel)" : "Drop what?", - true); + theItem = promptForItemOfType(ALL_ITEMS, 0, 0, KEYBOARD_LABELS ? "Drop what? (a-z, shift for more info; or to cancel)" : "Drop what?", true); } if (theItem == NULL) { return; @@ -7430,7 +6931,7 @@ void drop(item *theItem) { if (theItem->flags & ITEM_EQUIPPED) { unequipItem(theItem, false); } - theItem = dropItem(theItem); // This is where it gets dropped. + theItem = dropItem(theItem); // This is where it gets dropped. theItem->flags |= ITEM_PLAYER_AVOIDS; // Try not to pick up stuff you've already dropped. itemName(theItem, buf2, true, true, NULL); sprintf(buf, "You dropped %s.", buf2); @@ -7442,11 +6943,7 @@ void drop(item *theItem) { } } -item *promptForItemOfType(unsigned short category, - unsigned long requiredFlags, - unsigned long forbiddenFlags, - char *prompt, - boolean allowInventoryActions) { +item *promptForItemOfType(unsigned short category, unsigned long requiredFlags, unsigned long forbiddenFlags, char *prompt, boolean allowInventoryActions) { char keystroke; item *theItem; @@ -7497,7 +6994,8 @@ item *itemAtLoc(short x, short y) { if (!(pmap[x][y].flags & HAS_ITEM)) { return NULL; // easy optimization } - for (theItem = floorItems->nextItem; theItem != NULL && (theItem->loc.x != x || theItem->loc.y != y); theItem = theItem->nextItem); + for (theItem = floorItems->nextItem; theItem != NULL && (theItem->loc.x != x || theItem->loc.y != y); theItem = theItem->nextItem) + ; if (theItem == NULL) { pmap[x][y].flags &= ~HAS_ITEM; hiliteCell(x, y, &white, 75, true); @@ -7586,9 +7084,7 @@ boolean equipItem(item *theItem, boolean force, item *unequipHint) { previouslyEquippedItem = rogue.weapon; } else if (theItem->category & ARMOR) { previouslyEquippedItem = rogue.armor; - } else if (theItem->category & RING - && unequipHint && rogue.ringLeft && rogue.ringRight - && (unequipHint == rogue.ringLeft || unequipHint == rogue.ringRight)) { + } else if (theItem->category & RING && unequipHint && rogue.ringLeft && rogue.ringRight && (unequipHint == rogue.ringLeft || unequipHint == rogue.ringRight)) { previouslyEquippedItem = unequipHint; } @@ -7618,8 +7114,7 @@ boolean equipItem(item *theItem, boolean force, item *unequipHint) { updateClairvoyance(); displayLevel(); identifyItemKind(theItem); - } else if (theItem->kind == RING_LIGHT - || theItem->kind == RING_STEALTH) { + } else if (theItem->kind == RING_LIGHT || theItem->kind == RING_STEALTH) { identifyItemKind(theItem); } updateEncumbrance(); @@ -7641,7 +7136,7 @@ boolean equipItem(item *theItem, boolean force, item *unequipHint) { if (theItem->flags & ITEM_CURSED) { itemName(theItem, buf2, false, false, NULL); - switch(theItem->category) { + switch (theItem->category) { case WEAPON: sprintf(buf1, "you wince as your grip involuntarily tightens around your %s.", buf2); break; @@ -7671,9 +7166,7 @@ boolean unequipItem(item *theItem, boolean force) { } if ((theItem->flags & ITEM_CURSED) && !force) { itemName(theItem, buf2, false, false, NULL); - sprintf(buf, "you can't; your %s appear%s to be cursed.", - buf2, - theItem->quantity == 1 ? "s" : ""); + sprintf(buf, "you can't; your %s appear%s to be cursed.", buf2, theItem->quantity == 1 ? "s" : ""); confirmMessages(); messageWithColor(buf, &itemMessageColor, 0); return false; @@ -7712,11 +7205,10 @@ void updateRingBonuses() { short i; item *rings[2] = {rogue.ringLeft, rogue.ringRight}; - rogue.clairvoyance = rogue.stealthBonus = rogue.transference - = rogue.awarenessBonus = rogue.regenerationBonus = rogue.wisdomBonus = rogue.reaping = 0; + rogue.clairvoyance = rogue.stealthBonus = rogue.transference = rogue.awarenessBonus = rogue.regenerationBonus = rogue.wisdomBonus = rogue.reaping = 0; rogue.lightMultiplier = 1; - for (i=0; i<= 1; i++) { + for (i = 0; i <= 1; i++) { if (rings[i]) { switch (rings[i]->kind) { case RING_CLAIRVOYANCE: @@ -7772,15 +7264,14 @@ void updatePlayerRegenerationDelay() { } player.info.turnsBetweenRegen = (turnsForFull / maxHP); - // DEBUG printf("\nTurnsForFull: %i; regenPerTurn: %i; (thousandths of) turnsBetweenRegen: %i", turnsForFull, player.regenPerTurn, player.info.turnsBetweenRegen); + // DEBUG printf("\nTurnsForFull: %i; regenPerTurn: %i; (thousandths of) turnsBetweenRegen: %i", turnsForFull, + // player.regenPerTurn, player.info.turnsBetweenRegen); } boolean removeItemFromChain(item *theItem, item *theChain) { item *previousItem; - for (previousItem = theChain; - previousItem->nextItem; - previousItem = previousItem->nextItem) { + for (previousItem = theChain; previousItem->nextItem; previousItem = previousItem->nextItem) { if (previousItem->nextItem == theItem) { previousItem->nextItem = theItem->nextItem; return true; @@ -7794,9 +7285,7 @@ void addItemToChain(item *theItem, item *theChain) { theChain->nextItem = theItem; } -void deleteItem(item *theItem) { - free(theItem); -} +void deleteItem(item *theItem) { free(theItem); } void resetItemTableEntry(itemTable *theEntry) { theEntry->identified = false; @@ -7809,26 +7298,26 @@ void shuffleFlavors() { short i, j, randIndex, randNumber; char buf[COLS]; - for (i=0; inumberPotionKinds; i++) { + for (i = 0; i < gameConst->numberPotionKinds; i++) { resetItemTableEntry(potionTable + i); } - for (i=0; inumberWandKinds; i++) { + for (i = 0; i < gameConst->numberWandKinds; i++) { resetItemTableEntry(wandTable + i); } - for (i=0; inumberScrollKinds; i++) { + for (i = 0; i < gameConst->numberScrollKinds; i++) { resetItemTableEntry(scrollTable + i); } - for (i=0; i0) ? " " : ""), titlePhonemes[randIndex]); + sprintf(itemTitles[i], "%s%s%s", buf, ((rand_percent(50) && j > 0) ? " " : ""), titlePhonemes[randIndex]); } } } diff --git a/src/brogue/Light.c b/src/brogue/Light.c index 26b8d5f7..08b523e6 100644 --- a/src/brogue/Light.c +++ b/src/brogue/Light.c @@ -30,16 +30,16 @@ void logLights() { short i, j; printf(" "); - for (i=0; ipassThroughCreatures ? 0 : (HAS_MONSTER | HAS_PLAYER)), - (!isMinersLight)); + getFOVMask(grid, x, y, radius, T_OBSTRUCTS_VISION, (theLight->passThroughCreatures ? 0 : (HAS_MONSTER | HAS_PLAYER)), (!isMinersLight)); overlappedFieldOfView = false; for (i = max(0, x - radiusRounded); i < DCOLS && i < x + radiusRounded; i++) { for (j = max(0, y - radiusRounded); j < DROWS && j < y + radiusRounded; j++) { if (grid[i][j]) { - lightMultiplier = 100 - (100 - fadeToPercent) * fp_sqrt(((i-x) * (i-x) + (j-y) * (j-y)) * FP_FACTOR) / radius; - for (k=0; k<3; k++) { - tmap[i][j].light[k] += colorComponents[k] * lightMultiplier / 100;; + lightMultiplier = 100 - (100 - fadeToPercent) * fp_sqrt(((i - x) * (i - x) + (j - y) * (j - y)) * FP_FACTOR) / radius; + for (k = 0; k < 3; k++) { + tmap[i][j].light[k] += colorComponents[k] * lightMultiplier / 100; + ; } if (dispelShadows) { pmap[i][j].flags &= ~IS_IN_SHADOW; @@ -116,8 +116,8 @@ boolean paintLight(const lightSource *theLight, short x, short y, boolean isMine return overlappedFieldOfView; } - -// sets miner's light strength and characteristics based on rings of illumination, scrolls of darkness and water submersion +// sets miner's light strength and characteristics based on rings of illumination, scrolls of darkness and water +// submersion void updateMinersLightRadius() { fixpt base_fraction, fraction, lightRadius; @@ -133,7 +133,8 @@ void updateMinersLightRadius() { if (player.status[STATUS_DARKNESS]) { base_fraction = FP_FACTOR - player.status[STATUS_DARKNESS] * FP_FACTOR / player.maxStatus[STATUS_DARKNESS]; fraction = (base_fraction * base_fraction / FP_FACTOR) * base_fraction / FP_FACTOR; - //fraction = (double) pow(1.0 - (((double) player.status[STATUS_DARKNESS]) / player.maxStatus[STATUS_DARKNESS]), 3); + // fraction = (double) pow(1.0 - (((double) player.status[STATUS_DARKNESS]) / + // player.maxStatus[STATUS_DARKNESS]), 3); if (fraction < FP_FACTOR / 20) { fraction = FP_FACTOR / 20; } @@ -159,9 +160,7 @@ void updateDisplayDetail() { for (i = 0; i < DCOLS; i++) { for (j = 0; j < DROWS; j++) { - if (tmap[i][j].light[0] < -10 - && tmap[i][j].light[1] < -10 - && tmap[i][j].light[2] < -10) { + if (tmap[i][j].light[0] < -10 && tmap[i][j].light[1] < -10 && tmap[i][j].light[2] < -10) { displayDetail[i][j] = DV_DARK; } else if (pmap[i][j].flags & IS_IN_SHADOW) { @@ -175,9 +174,9 @@ void updateDisplayDetail() { void backUpLighting(short lights[DCOLS][DROWS][3]) { short i, j, k; - for (i=0; ilight[0] + 10 < minersLightColor.red - && tmapAt(player.loc)->light[1] + 10 < minersLightColor.green - && tmapAt(player.loc)->light[2] + 10 < minersLightColor.blue); -} +boolean playerInDarkness() { return (tmapAt(player.loc)->light[0] + 10 < minersLightColor.red && tmapAt(player.loc)->light[1] + 10 < minersLightColor.green && tmapAt(player.loc)->light[2] + 10 < minersLightColor.blue); } #define flarePrecision 1000 @@ -327,11 +322,11 @@ boolean flareIsActive(flare *theFlare) { active = false; } if (increasing) { - if ((short) (theFlare->coeff / flarePrecision) > theFlare->coeffLimit) { + if ((short)(theFlare->coeff / flarePrecision) > theFlare->coeffLimit) { active = false; } } else { - if ((short) (theFlare->coeff / flarePrecision) < theFlare->coeffLimit) { + if ((short)(theFlare->coeff / flarePrecision) < theFlare->coeffLimit) { active = false; } } @@ -357,8 +352,8 @@ boolean drawFlareFrame(flare *theFlare) { if (!flareIsActive(theFlare)) { return false; } - tempLight.lightRadius.lowerBound = ((long) tempLight.lightRadius.lowerBound) * theFlare->coeff / (flarePrecision * 100); - tempLight.lightRadius.upperBound = ((long) tempLight.lightRadius.upperBound) * theFlare->coeff / (flarePrecision * 100); + tempLight.lightRadius.lowerBound = ((long)tempLight.lightRadius.lowerBound) * theFlare->coeff / (flarePrecision * 100); + tempLight.lightRadius.upperBound = ((long)tempLight.lightRadius.upperBound) * theFlare->coeff / (flarePrecision * 100); applyColorScalar(&tempColor, theFlare->coeff / flarePrecision); tempLight.lightColor = &tempColor; inView = paintLight(&tempLight, theFlare->loc.x, theFlare->loc.y, false, true); @@ -406,7 +401,7 @@ void animateFlares(flare **flares, short count) { void deleteAllFlares() { short i; - for (i=0; i #include -#define MENU_FLAME_PRECISION_FACTOR 10 -#define MENU_FLAME_RISE_SPEED 50 -#define MENU_FLAME_SPREAD_SPEED 20 -#define MENU_FLAME_COLOR_DRIFT_SPEED 500 -#define MENU_FLAME_FADE_SPEED 20 -#define MENU_FLAME_UPDATE_DELAY 50 -#define MENU_FLAME_ROW_PADDING 2 -#define MENU_TITLE_OFFSET_X (-4) -#define MENU_TITLE_OFFSET_Y (-1) +#define MENU_FLAME_PRECISION_FACTOR 10 +#define MENU_FLAME_RISE_SPEED 50 +#define MENU_FLAME_SPREAD_SPEED 20 +#define MENU_FLAME_COLOR_DRIFT_SPEED 500 +#define MENU_FLAME_FADE_SPEED 20 +#define MENU_FLAME_UPDATE_DELAY 50 +#define MENU_FLAME_ROW_PADDING 2 +#define MENU_TITLE_OFFSET_X (-4) +#define MENU_TITLE_OFFSET_Y (-1) -#define MENU_FLAME_COLOR_SOURCE_COUNT 1136 - -#define MENU_FLAME_DENOMINATOR (100 + MENU_FLAME_RISE_SPEED + MENU_FLAME_SPREAD_SPEED) +#define MENU_FLAME_COLOR_SOURCE_COUNT 1136 +#define MENU_FLAME_DENOMINATOR (100 + MENU_FLAME_RISE_SPEED + MENU_FLAME_SPREAD_SPEED) void drawMenuFlames(signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3], unsigned char mask[COLS][ROWS]) { short i, j, versionStringLength; @@ -50,8 +49,8 @@ void drawMenuFlames(signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3 versionStringLength = strLenWithoutEscapes(gameConst->versionString); - for (j=0; j= COLS - versionStringLength) { dchar = gameConst->versionString[i - (COLS - versionStringLength)]; } else { @@ -59,39 +58,37 @@ void drawMenuFlames(signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3 } if (mask[i][j] == 100) { - plotCharWithColor(dchar, (windowpos){ i, j }, &veryDarkGray, maskColor); + plotCharWithColor(dchar, (windowpos){i, j}, &veryDarkGray, maskColor); } else { tempColor = black; - tempColor.red = flames[i][j][0] / MENU_FLAME_PRECISION_FACTOR; + tempColor.red = flames[i][j][0] / MENU_FLAME_PRECISION_FACTOR; tempColor.green = flames[i][j][1] / MENU_FLAME_PRECISION_FACTOR; - tempColor.blue = flames[i][j][2] / MENU_FLAME_PRECISION_FACTOR; + tempColor.blue = flames[i][j][2] / MENU_FLAME_PRECISION_FACTOR; if (mask[i][j] > 0) { applyColorAverage(&tempColor, maskColor, mask[i][j]); } - plotCharWithColor(dchar, (windowpos){ i, j }, &veryDarkGray, &tempColor); + plotCharWithColor(dchar, (windowpos){i, j}, &veryDarkGray, &tempColor); } } } } -void updateMenuFlames(const color *colors[COLS][(ROWS + MENU_FLAME_ROW_PADDING)], - signed short colorSources[MENU_FLAME_COLOR_SOURCE_COUNT][4], - signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3]) { +void updateMenuFlames(const color *colors[COLS][(ROWS + MENU_FLAME_ROW_PADDING)], signed short colorSources[MENU_FLAME_COLOR_SOURCE_COUNT][4], signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3]) { short i, j, k, l, x, y; signed short tempFlames[COLS][3]; short colorSourceNumber, rand; colorSourceNumber = 0; - for (j=0; j<(ROWS + MENU_FLAME_ROW_PADDING); j++) { + for (j = 0; j < (ROWS + MENU_FLAME_ROW_PADDING); j++) { // Make a temp copy of the current row. - for (i=0; irand * colorSources[colorSourceNumber][0] / 1000; - flames[i][j][0] += (colors[i][j]->red + (colors[i][j]->redRand * colorSources[colorSourceNumber][1] / 1000) + rand) * MENU_FLAME_PRECISION_FACTOR; - flames[i][j][1] += (colors[i][j]->green + (colors[i][j]->greenRand * colorSources[colorSourceNumber][2] / 1000) + rand) * MENU_FLAME_PRECISION_FACTOR; - flames[i][j][2] += (colors[i][j]->blue + (colors[i][j]->blueRand * colorSources[colorSourceNumber][3] / 1000) + rand) * MENU_FLAME_PRECISION_FACTOR; + flames[i][j][0] += (colors[i][j]->red + (colors[i][j]->redRand * colorSources[colorSourceNumber][1] / 1000) + rand) * MENU_FLAME_PRECISION_FACTOR; + flames[i][j][1] += (colors[i][j]->green + (colors[i][j]->greenRand * colorSources[colorSourceNumber][2] / 1000) + rand) * MENU_FLAME_PRECISION_FACTOR; + flames[i][j][2] += (colors[i][j]->blue + (colors[i][j]->blueRand * colorSources[colorSourceNumber][3] / 1000) + rand) * MENU_FLAME_PRECISION_FACTOR; colorSourceNumber++; } @@ -155,14 +152,14 @@ void antiAlias(unsigned char mask[COLS][ROWS]) { short i, j, x, y, dir, nbCount; const short intensity[5] = {0, 0, 35, 50, 60}; - for (i=0; imainMenuTitleWidth; i++) { - for (j=0; jmainMenuTitleHeight; j++) { + for (i = 0; i < gameConst->mainMenuTitleWidth; i++) { + for (j = 0; j < gameConst->mainMenuTitleHeight; j++) { if (mainMenuTitle[j * gameConst->mainMenuTitleWidth + i] != ' ') { - colors[(COLS - gameConst->mainMenuTitleWidth)/2 + i + MENU_TITLE_OFFSET_X][(ROWS - gameConst->mainMenuTitleHeight)/2 + j + MENU_TITLE_OFFSET_Y] = &flameTitleColor; + colors[(COLS - gameConst->mainMenuTitleWidth) / 2 + i + MENU_TITLE_OFFSET_X][(ROWS - gameConst->mainMenuTitleHeight) / 2 + j + MENU_TITLE_OFFSET_Y] = &flameTitleColor; colorSourceCount++; - mask[(COLS - gameConst->mainMenuTitleWidth)/2 + i + MENU_TITLE_OFFSET_X][(ROWS - gameConst->mainMenuTitleHeight)/2 + j + MENU_TITLE_OFFSET_Y] = 100; + mask[(COLS - gameConst->mainMenuTitleWidth) / 2 + i + MENU_TITLE_OFFSET_X][(ROWS - gameConst->mainMenuTitleHeight) / 2 + j + MENU_TITLE_OFFSET_Y] = 100; } } } @@ -231,15 +224,15 @@ void initializeMenuFlames(boolean includeTitle, brogueAssert(colorSourceCount <= MENU_FLAME_COLOR_SOURCE_COUNT); // Simulate the background flames for a while - for (i=0; i<100; i++) { + for (i = 0; i < 100; i++) { updateMenuFlames(colors, colorSources, flames); } - } void titleMenu() { signed short flames[COLS][(ROWS + MENU_FLAME_ROW_PADDING)][3]; // red, green and blue - signed short colorSources[MENU_FLAME_COLOR_SOURCE_COUNT][4]; // red, green, blue, and rand, one for each color source (no more than MENU_FLAME_COLOR_SOURCE_COUNT). + signed short colorSources[MENU_FLAME_COLOR_SOURCE_COUNT][4]; // red, green, blue, and rand, one for each color + // source (no more than MENU_FLAME_COLOR_SOURCE_COUNT). const color *colors[COLS][(ROWS + MENU_FLAME_ROW_PADDING)]; color colorStorage[COLS]; unsigned char mask[COLS][ROWS]; @@ -304,7 +297,7 @@ void titleMenu() { x = COLS - 1 - 20 - 2; y = ROWS - 1; - for (i = b-1; i >= 0; i--) { + for (i = b - 1; i >= 0; i--) { y -= 2; buttons[i].x = x; buttons[i].y = y; @@ -314,8 +307,8 @@ void titleMenu() { blackOutScreen(); clearDisplayBuffer(shadowBuf); - initializeButtonState(&state, buttons, b, x, y, 20, b*2-1); - rectangularShading(x, y, 20, b*2-1, &black, INTERFACE_OPACITY, shadowBuf); + initializeButtonState(&state, buttons, b, x, y, 20, b * 2 - 1); + rectangularShading(x, y, 20, b * 2 - 1, &black, INTERFACE_OPACITY, shadowBuf); drawButtonsInState(&state); initializeMenuFlames(true, colors, colorStorage, colorSources, flames, mask); @@ -394,13 +387,13 @@ void dialogAlert(char *message) { strcpy(OKButton.text, " OK "); OKButton.hotkey[0] = RETURN_KEY; OKButton.hotkey[1] = ACKNOWLEDGE_KEY; - printTextBox(message, COLS/3, ROWS/3, COLS/3, &white, &interfaceBoxColor, rbuf, &OKButton, 1); + printTextBox(message, COLS / 3, ROWS / 3, COLS / 3, &white, &interfaceBoxColor, rbuf, &OKButton, 1); overlayDisplayBuffer(rbuf, NULL); } boolean stringsExactlyMatch(const char *string1, const char *string2) { short i; - for (i=0; string1[i] && string2[i]; i++) { + for (i = 0; string1[i] && string2[i]; i++) { if (string1[i] != string2[i]) { return false; } @@ -423,19 +416,19 @@ int fileEntryCompareDates(const void *a, const void *b) { t2 = mktime(&f2->date); diff = difftime(t2, t1); - //char date_f1[11]; - //char date_f2[11]; - //strftime(date_f1, sizeof(date_f1), DATE_FORMAT, &f1->date); - //strftime(date_f2, sizeof(date_f2), DATE_FORMAT, &f2->date); - //printf("\nf1: %s\t%s",date_f1,f1->path); - //printf("\nf2: %s\t%s",date_f2,f2->path); - //printf("\ndiff: %f\n", diff); + // char date_f1[11]; + // char date_f2[11]; + // strftime(date_f1, sizeof(date_f1), DATE_FORMAT, &f1->date); + // strftime(date_f2, sizeof(date_f2), DATE_FORMAT, &f2->date); + // printf("\nf1: %s\t%s",date_f1,f1->path); + // printf("\nf2: %s\t%s",date_f2,f2->path); + // printf("\ndiff: %f\n", diff); return (int)diff; } -#define FILES_ON_PAGE_MAX (min(26, ROWS - 7)) // Two rows (top and bottom) for flames, two rows for border, one for prompt, one for heading. -#define MAX_FILENAME_DISPLAY_LENGTH 53 +#define FILES_ON_PAGE_MAX (min(26, ROWS - 7)) // Two rows (top and bottom) for flames, two rows for border, one for prompt, one for heading. +#define MAX_FILENAME_DISPLAY_LENGTH 53 boolean dialogChooseFile(char *path, const char *suffix, const char *prompt) { short i, j, count, x, y, width, height, suffixLength, pathLength, maxPathLength, currentPageStart; brogueButton buttons[FILES_ON_PAGE_MAX + 2]; @@ -444,7 +437,7 @@ boolean dialogChooseFile(char *path, const char *suffix, const char *prompt) { cellDisplayBuffer dbuf[COLS][ROWS], rbuf[COLS][ROWS]; const color *dialogColor = &interfaceBoxColor; char *membuf; - char fileDate [11]; + char fileDate[11]; suffixLength = strlen(suffix); files = listFiles(&count, &membuf); @@ -453,16 +446,16 @@ boolean dialogChooseFile(char *path, const char *suffix, const char *prompt) { // First, we want to filter the list by stripping out any filenames that do not end with suffix. // i is the entry we're testing, and j is the entry that we move it to if it qualifies. - for (i=0, j=0; i j) { files[j] = files[i]; - //strftime(fileDate, sizeof(fileDate), DATE_FORMAT, &files[j].date); - //printf("\nMatching file: %s\twith date: %s", files[j].path, fileDate); + // strftime(fileDate, sizeof(fileDate), DATE_FORMAT, &files[j].date); + // printf("\nMatching file: %s\twith date: %s", files[j].path, fileDate); } j++; @@ -482,7 +475,7 @@ boolean dialogChooseFile(char *path, const char *suffix, const char *prompt) { do { // Repeat to permit scrolling. again = false; - for (i=0; i FILES_ON_PAGE_MAX ? 2 : 0), - x, - y, - width, - height, - NULL); - -// for (j=0; j FILES_ON_PAGE_MAX ? 2 : 0), x, y, width, height, NULL); + + // for (j=0; j= 0) { retval = true; - strcpy(path, files[currentPageStart+i].path); + strcpy(path, files[currentPageStart + i].path); } else { // i is -1 retval = false; } @@ -626,15 +613,15 @@ void mainBrogueJunction() { short i, j, k; // clear screen and display buffer - for (i=0; i>(32-(k)))) -u4 ranval( ranctx *x ) { +#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) +u4 ranval(ranctx *x) { u4 e = x->a - rot(x->b, 27); x->a = x->b ^ rot(x->c, 17); x->b = x->c + x->d; @@ -103,11 +103,11 @@ u4 ranval( ranctx *x ) { return x->d; } -void raninit( ranctx *x, uint64_t seed ) { +void raninit(ranctx *x, uint64_t seed) { u4 i; x->a = 0xf1ea5eed, x->b = x->c = x->d = (u4)seed; x->c ^= (u4)(seed >> 32); - for (i=0; i<20; ++i) { + for (i = 0; i < 20; ++i) { (void)ranval(x); } } @@ -120,13 +120,13 @@ void raninit( ranctx *x, uint64_t seed ) { */ -#define RAND_MAX_COMBO ((unsigned long) UINT32_MAX) +#define RAND_MAX_COMBO ((unsigned long)UINT32_MAX) long range(long n, short RNG) { unsigned long div; long r; - div = RAND_MAX_COMBO/n; + div = RAND_MAX_COMBO / n; do { r = ranval(&(RNGState[RNG])) / div; @@ -149,7 +149,7 @@ long rand_range(long lowerBound, long upperBound) { retval = lowerBound + range(interval, rogue.RNG); if (rogue.RNG == RNG_SUBSTANTIVE) { randomNumbersGenerated++; - if (1) { //randomNumbersGenerated >= 1128397) { + if (1) { // randomNumbersGenerated >= 1128397) { sprintf(RNGMessage, "\n#%lu, %ld to %ld: %ld", randomNumbersGenerated, lowerBound, upperBound, retval); RNGLog(RNGMessage); } @@ -183,15 +183,14 @@ uint64_t rand_64bits() { // All RNGs are seeded simultaneously and identically. uint64_t seedRandomGenerator(uint64_t seed) { if (seed == 0) { - seed = (uint64_t) time(NULL) - 1352700000; + seed = (uint64_t)time(NULL) - 1352700000; } raninit(&(RNGState[RNG_SUBSTANTIVE]), seed); raninit(&(RNGState[RNG_COSMETIC]), seed); return seed; } - - // Fixed-point arithmetic +// Fixed-point arithmetic fixpt fp_round(fixpt x) { long long div = x / FP_FACTOR, rem = x % FP_FACTOR; @@ -215,24 +214,19 @@ static int msbpos(unsigned long long x) { return n; } -static fixpt fp_exp2(int n) { - return (n >= 0 ? FP_FACTOR << n : FP_FACTOR >> -n); -} +static fixpt fp_exp2(int n) { return (n >= 0 ? FP_FACTOR << n : FP_FACTOR >> -n); } // Calculates sqrt(u) using the bisection method to find the root of // f(x) = x^2 - u. fixpt fp_sqrt(fixpt u) { - static const fixpt SQUARE_ROOTS[] = { // values were computed by the code that follows - 0, 65536, 92682, 113511, 131073, 146543, 160529, 173392, 185363, 196608, 207243, 217359, 227023, 236293, 245213, 253819, - 262145, 270211, 278045, 285665, 293086, 300323, 307391, 314299, 321059, 327680, 334169, 340535, 346784, 352923, 358955, 364889, - 370727, 376475, 382137, 387717, 393216, 398640, 403991, 409273, 414487, 419635, 424721, 429749, 434717, 439629, 444487, 449293, - 454047, 458752, 463409, 468021, 472587, 477109, 481589, 486028, 490427, 494786, 499107, 503391, 507639, 511853, 516031, 520175, - 524289, 528369, 532417, 536435, 540423, 544383, 548313, 552217, 556091, 559939, 563762, 567559, 571329, 575077, 578799, 582497, - 586171, 589824, 593453, 597061, 600647, 604213, 607755, 611279, 614783, 618265, 621729, 625173, 628599, 632007, 635395, 638765, - 642119, 645455, 648773, 652075, 655360, 658629, 661881, 665117, 668339, 671545, 674735, 677909, 681071, 684215, 687347, 690465, - 693567, 696657, 699733, 702795, 705845, 708881, 711903, 714913, 717911, 720896, 723869, 726829, 729779, 732715, 735639, 738553 - }; + static const fixpt SQUARE_ROOTS[] + = {// values were computed by the code that follows + 0, 65536, 92682, 113511, 131073, 146543, 160529, 173392, 185363, 196608, 207243, 217359, 227023, 236293, 245213, 253819, 262145, 270211, 278045, 285665, 293086, 300323, 307391, 314299, 321059, 327680, + 334169, 340535, 346784, 352923, 358955, 364889, 370727, 376475, 382137, 387717, 393216, 398640, 403991, 409273, 414487, 419635, 424721, 429749, 434717, 439629, 444487, 449293, 454047, 458752, 463409, 468021, + 472587, 477109, 481589, 486028, 490427, 494786, 499107, 503391, 507639, 511853, 516031, 520175, 524289, 528369, 532417, 536435, 540423, 544383, 548313, 552217, 556091, 559939, 563762, 567559, 571329, 575077, + 578799, 582497, 586171, 589824, 593453, 597061, 600647, 604213, 607755, 611279, 614783, 618265, 621729, 625173, 628599, 632007, 635395, 638765, 642119, 645455, 648773, 652075, 655360, 658629, 661881, 665117, + 668339, 671545, 674735, 677909, 681071, 684215, 687347, 690465, 693567, 696657, 699733, 702795, 705845, 708881, 711903, 714913, 717911, 720896, 723869, 726829, 729779, 732715, 735639, 738553}; if (u < 0) return -fp_sqrt(-u); @@ -249,7 +243,7 @@ fixpt fp_sqrt(fixpt u) { // Since 2^(k-1) <= u < 2^k, we have 2^(ceil(k/2)-1) <= sqrt(u) < 2^ceil(k/2). // First ineq. from sqrt(u) >= 2^[(k-1)/2] = 2^[k/2 + 1/2 - 1] >= 2^(ceil(k/2) - 1) // To calculate ceil(k/2), do k/2 but add 1 to k if positive. - upper = fp_exp2((k + (k > 0))/2); + upper = fp_exp2((k + (k > 0)) / 2); lower = upper / 2; while (upper != lower + 1) { diff --git a/src/brogue/Monsters.c b/src/brogue/Monsters.c index 932e48d2..6c0a0349 100644 --- a/src/brogue/Monsters.c +++ b/src/brogue/Monsters.c @@ -66,10 +66,7 @@ creature *generateMonster(short monsterID, boolean itemPossible, boolean mutatio monst->info = monsterCatalog[monsterID]; monst->mutationIndex = -1; - if (mutationPossible - && !(monst->info.flags & MONST_NEVER_MUTATED) - && !(monst->info.abilityFlags & MA_NEVER_MUTATED) - && rogue.depthLevel > gameConst->mutationsOccurAboveLevel) { + if (mutationPossible && !(monst->info.flags & MONST_NEVER_MUTATED) && !(monst->info.abilityFlags & MA_NEVER_MUTATED) && rogue.depthLevel > gameConst->mutationsOccurAboveLevel) { if (rogue.depthLevel <= gameConst->amuletLevel) { mutationChance = clamp((rogue.depthLevel - gameConst->mutationsOccurAboveLevel) * gameConst->depthAccelerator, 1, 10); @@ -80,8 +77,7 @@ creature *generateMonster(short monsterID, boolean itemPossible, boolean mutatio if (rand_percent(mutationChance)) { mutationAttempt = rand_range(0, NUMBER_MUTATORS - 1); - if (!(monst->info.flags & mutationCatalog[mutationAttempt].forbiddenFlags) - && !(monst->info.abilityFlags & mutationCatalog[mutationAttempt].forbiddenAbilityFlags)) { + if (!(monst->info.flags & mutationCatalog[mutationAttempt].forbiddenFlags) && !(monst->info.abilityFlags & mutationCatalog[mutationAttempt].forbiddenAbilityFlags)) { mutateMonster(monst, mutationAttempt); } @@ -96,8 +92,7 @@ creature *generateMonster(short monsterID, boolean itemPossible, boolean mutatio monst->safetyMap = NULL; monst->leader = NULL; monst->carriedMonster = NULL; - monst->creatureState = (((monst->info.flags & MONST_NEVER_SLEEPS) || rand_percent(25)) - ? MONSTER_TRACKING_SCENT : MONSTER_SLEEPING); + monst->creatureState = (((monst->info.flags & MONST_NEVER_SLEEPS) || rand_percent(25)) ? MONSTER_TRACKING_SCENT : MONSTER_SLEEPING); monst->creatureMode = MODE_NORMAL; monst->currentHP = monst->info.maxHP; monst->spawnDepth = rogue.depthLevel; @@ -114,7 +109,7 @@ creature *generateMonster(short monsterID, boolean itemPossible, boolean mutatio monst->targetCorpseLoc = INVALID_POS; monst->lastSeenPlayerAt = INVALID_POS; monst->targetWaypointIndex = -1; - for (i=0; i < MAX_WAYPOINT_COUNT; i++) { + for (i = 0; i < MAX_WAYPOINT_COUNT; i++) { monst->waypointAlreadyVisited[i] = rand_range(0, 1); } @@ -140,11 +135,7 @@ creature *generateMonster(short monsterID, boolean itemPossible, boolean mutatio itemChance = 0; } - if (ITEMS_ENABLED - && itemPossible - && (rogue.depthLevel <= gameConst->amuletLevel) - && monsterItemsHopper->nextItem - && rand_percent(itemChance)) { + if (ITEMS_ENABLED && itemPossible && (rogue.depthLevel <= gameConst->amuletLevel) && monsterItemsHopper->nextItem && rand_percent(itemChance)) { monst->carriedItem = monsterItemsHopper->nextItem; monsterItemsHopper->nextItem = monsterItemsHopper->nextItem->nextItem; @@ -178,9 +169,7 @@ boolean monsterRevealed(creature *monst) { boolean monsterHiddenBySubmersion(const creature *monst, const creature *observer) { if (monst->bookkeepingFlags & MB_SUBMERGED) { - if (observer - && (terrainFlags(observer->loc.x, observer->loc.y) & T_IS_DEEP_WATER) - && !observer->status[STATUS_LEVITATING]) { + if (observer && (terrainFlags(observer->loc.x, observer->loc.y) & T_IS_DEEP_WATER) && !observer->status[STATUS_LEVITATING]) { // observer is in deep water, so target is not hidden by water return false; } else { @@ -213,8 +202,7 @@ boolean canSeeMonster(creature *monst) { if (monst == &player) { return true; } - if (!monsterIsHidden(monst, &player) - && (playerCanSee(monst->loc.x, monst->loc.y) || monsterRevealed(monst))) { + if (!monsterIsHidden(monst, &player) && (playerCanSee(monst->loc.x, monst->loc.y) || monsterRevealed(monst))) { return true; } return false; @@ -243,16 +231,14 @@ void monsterName(char *buf, creature *monst, boolean includeArticle) { oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; - sprintf(buf, "%s%s", (includeArticle ? "the " : ""), - monsterCatalog[rand_range(1, NUMBER_MONSTER_KINDS - 1)].monsterName); + // assureCosmeticRNG; + sprintf(buf, "%s%s", (includeArticle ? "the " : ""), monsterCatalog[rand_range(1, NUMBER_MONSTER_KINDS - 1)].monsterName); restoreRNG; return; } - sprintf(buf, "%s%s", (includeArticle ? (monst->creatureState == MONSTER_ALLY ? "your " : "the ") : ""), - monst->info.monsterName); - //monsterText[monst->info.monsterID].name); + sprintf(buf, "%s%s", (includeArticle ? (monst->creatureState == MONSTER_ALLY ? "your " : "the ") : ""), monst->info.monsterName); + // monsterText[monst->info.monsterID].name); return; } else { strcpy(buf, "something"); @@ -274,24 +260,20 @@ boolean monsterIsInClass(const creature *monst, const short monsterClass) { // Don't attack a monster embedded in obstruction crystal. // Etc. boolean attackWouldBeFutile(const creature *attacker, const creature *defender) { - if (cellHasTerrainFlag(defender->loc.x, defender->loc.y, T_OBSTRUCTS_PASSABILITY) - && !(defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { + if (cellHasTerrainFlag(defender->loc.x, defender->loc.y, T_OBSTRUCTS_PASSABILITY) && !(defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { return true; } if (attacker == &player) { // Let the player do what she wants, if it's possible. return false; } - if ((attacker->info.flags & MONST_RESTRICTED_TO_LIQUID) - && !(attacker->status[STATUS_LEVITATING]) - && defender->status[STATUS_LEVITATING]) { + if ((attacker->info.flags & MONST_RESTRICTED_TO_LIQUID) && !(attacker->status[STATUS_LEVITATING]) && defender->status[STATUS_LEVITATING]) { return true; } if (defender->info.flags & MONST_INVULNERABLE) { return true; } - if (defender->info.flags & MONST_IMMUNE_TO_WEAPONS - && !(attacker->info.abilityFlags & MA_POISONS)) { + if (defender->info.flags & MONST_IMMUNE_TO_WEAPONS && !(attacker->info.abilityFlags & MA_POISONS)) { return true; } return false; @@ -305,33 +287,26 @@ boolean monsterWillAttackTarget(const creature *attacker, const creature *defend if (attacker == defender || (defender->bookkeepingFlags & MB_IS_DYING)) { return false; } - if (attacker == &player - && defender->creatureState == MONSTER_ALLY) { + if (attacker == &player && defender->creatureState == MONSTER_ALLY) { return false; } - if (attacker->status[STATUS_ENTRANCED] - && defender->creatureState != MONSTER_ALLY) { + if (attacker->status[STATUS_ENTRANCED] && defender->creatureState != MONSTER_ALLY) { return true; } - if (attacker->creatureState == MONSTER_ALLY - && attacker != &player - && defender->status[STATUS_ENTRANCED]) { + if (attacker->creatureState == MONSTER_ALLY && attacker != &player && defender->status[STATUS_ENTRANCED]) { return false; } if (defender->bookkeepingFlags & MB_CAPTIVE) { return false; } - if (attacker->status[STATUS_DISCORDANT] - || defender->status[STATUS_DISCORDANT] - || attacker->status[STATUS_CONFUSED]) { + if (attacker->status[STATUS_DISCORDANT] || defender->status[STATUS_DISCORDANT] || attacker->status[STATUS_CONFUSED]) { return true; } - if (monstersAreEnemies(attacker, defender) - && !monstersAreTeammates(attacker, defender)) { + if (monstersAreEnemies(attacker, defender) && !monstersAreTeammates(attacker, defender)) { return true; } return false; @@ -339,13 +314,11 @@ boolean monsterWillAttackTarget(const creature *attacker, const creature *defend boolean monstersAreTeammates(const creature *monst1, const creature *monst2) { // if one follows the other, or the other follows the one, or they both follow the same - return ((((monst1->bookkeepingFlags & MB_FOLLOWER) && monst1->leader == monst2) - || ((monst2->bookkeepingFlags & MB_FOLLOWER) && monst2->leader == monst1) - || (monst1->creatureState == MONSTER_ALLY && monst2 == &player) - || (monst1 == &player && monst2->creatureState == MONSTER_ALLY) - || (monst1->creatureState == MONSTER_ALLY && monst2->creatureState == MONSTER_ALLY) - || ((monst1->bookkeepingFlags & MB_FOLLOWER) && (monst2->bookkeepingFlags & MB_FOLLOWER) - && monst1->leader == monst2->leader)) ? true : false); + return ((((monst1->bookkeepingFlags & MB_FOLLOWER) && monst1->leader == monst2) || ((monst2->bookkeepingFlags & MB_FOLLOWER) && monst2->leader == monst1) || (monst1->creatureState == MONSTER_ALLY && monst2 == &player) + || (monst1 == &player && monst2->creatureState == MONSTER_ALLY) || (monst1->creatureState == MONSTER_ALLY && monst2->creatureState == MONSTER_ALLY) + || ((monst1->bookkeepingFlags & MB_FOLLOWER) && (monst2->bookkeepingFlags & MB_FOLLOWER) && monst1->leader == monst2->leader)) + ? true + : false); } boolean monstersAreEnemies(const creature *monst1, const creature *monst2) { @@ -359,23 +332,15 @@ boolean monstersAreEnemies(const creature *monst1, const creature *monst2) { return true; } // eels and krakens attack anything in deep water - if (((monst1->info.flags & MONST_RESTRICTED_TO_LIQUID) - && !(monst2->info.flags & MONST_IMMUNE_TO_WATER) - && !(monst2->status[STATUS_LEVITATING]) - && cellHasTerrainFlag(monst2->loc.x, monst2->loc.y, T_IS_DEEP_WATER)) + if (((monst1->info.flags & MONST_RESTRICTED_TO_LIQUID) && !(monst2->info.flags & MONST_IMMUNE_TO_WATER) && !(monst2->status[STATUS_LEVITATING]) && cellHasTerrainFlag(monst2->loc.x, monst2->loc.y, T_IS_DEEP_WATER)) - || ((monst2->info.flags & MONST_RESTRICTED_TO_LIQUID) - && !(monst1->info.flags & MONST_IMMUNE_TO_WATER) - && !(monst1->status[STATUS_LEVITATING]) - && cellHasTerrainFlag(monst1->loc.x, monst1->loc.y, T_IS_DEEP_WATER))) { + || ((monst2->info.flags & MONST_RESTRICTED_TO_LIQUID) && !(monst1->info.flags & MONST_IMMUNE_TO_WATER) && !(monst1->status[STATUS_LEVITATING]) && cellHasTerrainFlag(monst1->loc.x, monst1->loc.y, T_IS_DEEP_WATER))) { - return true; - } - return ((monst1->creatureState == MONSTER_ALLY || monst1 == &player) - != (monst2->creatureState == MONSTER_ALLY || monst2 == &player)); + return true; + } + return ((monst1->creatureState == MONSTER_ALLY || monst1 == &player) != (monst2->creatureState == MONSTER_ALLY || monst2 == &player)); } - void initializeGender(creature *monst) { if ((monst->info.flags & MONST_MALE) && (monst->info.flags & MONST_FEMALE)) { monst->info.flags &= ~(rand_percent(50) ? MONST_MALE : MONST_FEMALE); @@ -386,7 +351,7 @@ void initializeGender(creature *monst) { boolean stringsMatch(const char *str1, const char *str2) { short i; - for (i=0; str1[i] && str2[i]; i++) { + for (i = 0; str1[i] && str2[i]; i++) { if (str1[i] != str2[i]) { return false; } @@ -406,11 +371,7 @@ void resolvePronounEscapes(char *text, creature *monst) { boolean capitalize; // Note: Escape sequences MUST be longer than EACH of the possible replacements. // That way, the string only contracts, and we don't need a buffer. - const char pronouns[4][5][20] = { - {"$HESHE", "you", "he", "she", "it"}, - {"$HIMHER", "you", "him", "her", "it"}, - {"$HISHER", "your", "his", "her", "its"}, - {"$HIMSELFHERSELF", "yourself", "himself", "herself", "itself"}}; + const char pronouns[4][5][20] = {{"$HESHE", "you", "he", "she", "it"}, {"$HIMHER", "you", "him", "her", "it"}, {"$HISHER", "your", "his", "her", "its"}, {"$HIMSELFHERSELF", "yourself", "himself", "herself", "itself"}}; if (monst == &player) { gender = 1; @@ -428,7 +389,7 @@ void resolvePronounEscapes(char *text, creature *monst) { for (insert = scan = text; *scan;) { if (scan[0] == '$') { - for (pronounType=0; pronounType<4; pronounType++) { + for (pronounType = 0; pronounType < 4; pronounType++) { if (stringsMatch(pronouns[pronounType][0], scan)) { strcpy(insert, pronouns[pronounType][gender]); if (capitalize) { @@ -445,7 +406,7 @@ void resolvePronounEscapes(char *text, creature *monst) { *(insert++) = *(scan++); } } else if (scan[0] == COLOR_ESCAPE) { - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { *(insert++) = *(scan++); } } else { // Didn't match any of the escape sequences; copy the character instead. @@ -474,12 +435,10 @@ short pickHordeType(short depth, enum monsterTypes summonerType, unsigned long f depth = rogue.depthLevel; } - for (i=0; inumberHordes; i++) { - if (!(hordeCatalog[i].flags & forbiddenFlags) - && !(~(hordeCatalog[i].flags) & requiredFlags) - && ((!summonerType && hordeCatalog[i].minLevel <= depth && hordeCatalog[i].maxLevel >= depth) - || (summonerType && (hordeCatalog[i].flags & HORDE_IS_SUMMONED) && hordeCatalog[i].leaderType == summonerType))) { - possCount += hordeCatalog[i].frequency; + for (i = 0; i < gameConst->numberHordes; i++) { + if (!(hordeCatalog[i].flags & forbiddenFlags) && !(~(hordeCatalog[i].flags) & requiredFlags) + && ((!summonerType && hordeCatalog[i].minLevel <= depth && hordeCatalog[i].maxLevel >= depth) || (summonerType && (hordeCatalog[i].flags & HORDE_IS_SUMMONED) && hordeCatalog[i].leaderType == summonerType))) { + possCount += hordeCatalog[i].frequency; } } @@ -489,16 +448,14 @@ short pickHordeType(short depth, enum monsterTypes summonerType, unsigned long f index = rand_range(1, possCount); - for (i=0; inumberHordes; i++) { - if (!(hordeCatalog[i].flags & forbiddenFlags) - && !(~(hordeCatalog[i].flags) & requiredFlags) - && ((!summonerType && hordeCatalog[i].minLevel <= depth && hordeCatalog[i].maxLevel >= depth) - || (summonerType && (hordeCatalog[i].flags & HORDE_IS_SUMMONED) && hordeCatalog[i].leaderType == summonerType))) { - if (index <= hordeCatalog[i].frequency) { - return i; - } - index -= hordeCatalog[i].frequency; + for (i = 0; i < gameConst->numberHordes; i++) { + if (!(hordeCatalog[i].flags & forbiddenFlags) && !(~(hordeCatalog[i].flags) & requiredFlags) + && ((!summonerType && hordeCatalog[i].minLevel <= depth && hordeCatalog[i].maxLevel >= depth) || (summonerType && (hordeCatalog[i].flags & HORDE_IS_SUMMONED) && hordeCatalog[i].leaderType == summonerType))) { + if (index <= hordeCatalog[i].frequency) { + return i; } + index -= hordeCatalog[i].frequency; + } } return 0; // should never happen } @@ -541,8 +498,10 @@ creature *cloneMonster(creature *monst, boolean announce, boolean placeClone) { newMonst->carriedItem = NULL; if (monst->carriedMonster) { creature *parentMonst = cloneMonster(monst->carriedMonster, false, false); // Also clone the carriedMonster - removeCreature(monsters, parentMonst); // The cloned create will be added to the world, which we immediately undo. - removeCreature(dormantMonsters, parentMonst); // in case it's added as a dormant creature? TODO: is this possible? + removeCreature(monsters, + parentMonst); // The cloned create will be added to the world, which we immediately undo. + removeCreature(dormantMonsters, + parentMonst); // in case it's added as a dormant creature? TODO: is this possible? } newMonst->ticksUntilTurn = 101; if (!(monst->creatureState == MONSTER_ALLY)) { @@ -561,12 +520,10 @@ creature *cloneMonster(creature *monst, boolean announce, boolean placeClone) { } if (placeClone) { -// getQualifyingLocNear(loc, monst->loc.x, monst->loc.y, true, 0, forbiddenFlagsForMonster(&(monst->info)), (HAS_PLAYER | HAS_MONSTER), false, false); -// newMonst->loc.x = loc[0]; -// newMonst->loc.y = loc[1]; - getQualifyingPathLocNear(&(newMonst->loc.x), &(newMonst->loc.y), monst->loc.x, monst->loc.y, true, - T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(newMonst->info)), HAS_PLAYER, - avoidedFlagsForMonster(&(newMonst->info)), (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); + // getQualifyingLocNear(loc, monst->loc.x, monst->loc.y, true, 0, forbiddenFlagsForMonster(&(monst->info)), + // (HAS_PLAYER | HAS_MONSTER), false, false); newMonst->loc.x = loc[0]; newMonst->loc.y = loc[1]; + getQualifyingPathLocNear(&(newMonst->loc.x), &(newMonst->loc.y), monst->loc.x, monst->loc.y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(newMonst->info)), HAS_PLAYER, avoidedFlagsForMonster(&(newMonst->info)), + (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); pmapAt(newMonst->loc)->flags |= HAS_MONSTER; refreshDungeonCell(newMonst->loc.x, newMonst->loc.y); if (announce && canSeeMonster(newMonst)) { @@ -586,15 +543,12 @@ creature *cloneMonster(creature *monst, boolean announce, boolean placeClone) { newMonst->creatureState = MONSTER_ALLY; } - if (monst->creatureState == MONSTER_ALLY - && (monst->info.abilityFlags & MA_CLONE_SELF_ON_DEFEND) - && !rogue.featRecord[FEAT_JELLYMANCER]) { + if (monst->creatureState == MONSTER_ALLY && (monst->info.abilityFlags & MA_CLONE_SELF_ON_DEFEND) && !rogue.featRecord[FEAT_JELLYMANCER]) { jellyCount = 0; for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *nextMonst = nextCreature(&it); - if (nextMonst->creatureState == MONSTER_ALLY - && (nextMonst->info.abilityFlags & MA_CLONE_SELF_ON_DEFEND)) { + if (nextMonst->creatureState == MONSTER_ALLY && (nextMonst->info.abilityFlags & MA_CLONE_SELF_ON_DEFEND)) { jellyCount++; } @@ -649,13 +603,9 @@ unsigned long avoidedFlagsForMonster(creatureType *monsterType) { } boolean monsterCanSubmergeNow(creature *monst) { - return ((monst->info.flags & MONST_SUBMERGES) - && cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING) - && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY) + return ((monst->info.flags & MONST_SUBMERGES) && cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING) && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY) && !(monst->bookkeepingFlags & (MB_SEIZING | MB_SEIZED | MB_CAPTIVE)) - && ((monst->info.flags & (MONST_IMMUNE_TO_FIRE | MONST_INVULNERABLE)) - || monst->status[STATUS_IMMUNE_TO_FIRE] - || !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_LAVA_INSTA_DEATH))); + && ((monst->info.flags & (MONST_IMMUNE_TO_FIRE | MONST_INVULNERABLE)) || monst->status[STATUS_IMMUNE_TO_FIRE] || !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_LAVA_INSTA_DEATH))); } // Returns true if at least one minion spawned. @@ -685,9 +635,7 @@ boolean spawnMinions(short hordeID, creature *leader, boolean summoned, boolean monst = generateMonster(theHorde->memberType[iSpecies], itemPossible, !summoned); failsafe = 0; do { - getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), x, y, summoned, - T_DIVIDES_LEVEL & forbiddenTerrainFlags, (HAS_PLAYER | HAS_STAIRS), - forbiddenTerrainFlags, HAS_MONSTER, false); + getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), x, y, summoned, T_DIVIDES_LEVEL & forbiddenTerrainFlags, (HAS_PLAYER | HAS_STAIRS), forbiddenTerrainFlags, HAS_MONSTER, false); } while (theHorde->spawnsIn && !cellHasTerrainType(monst->loc.x, monst->loc.y, theHorde->spawnsIn) && failsafe++ < 20); if (failsafe >= 20) { // abort @@ -724,9 +672,7 @@ boolean drawManacle(short x, short y, enum directions dir) { enum tileType manacles[8] = {MANACLE_T, MANACLE_B, MANACLE_L, MANACLE_R, MANACLE_TL, MANACLE_BL, MANACLE_TR, MANACLE_BR}; short newX = x + nbDirs[dir][0]; short newY = y + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && pmap[newX][newY].layers[DUNGEON] == FLOOR - && pmap[newX][newY].layers[LIQUID] == NOTHING) { + if (coordinatesAreInMap(newX, newY) && pmap[newX][newY].layers[DUNGEON] == FLOOR && pmap[newX][newY].layers[LIQUID] == NOTHING) { pmap[x + nbDirs[dir][0]][y + nbDirs[dir][1]].layers[SURFACE] = manacles[dir]; return true; @@ -738,13 +684,13 @@ void drawManacles(short x, short y) { enum directions fallback[4][3] = {{UPLEFT, UP, LEFT}, {DOWNLEFT, DOWN, LEFT}, {UPRIGHT, UP, RIGHT}, {DOWNRIGHT, DOWN, RIGHT}}; short i, j; for (i = 0; i < 4; i++) { - for (j = 0; j < 3 && !drawManacle(x, y, fallback[i][j]); j++); + for (j = 0; j < 3 && !drawManacle(x, y, fallback[i][j]); j++) + ; } } -// If hordeID is 0, it's randomly assigned based on the depth, with a 10% chance of an out-of-depth spawn from 1-5 levels deeper. -// If x is negative, location is random. -// Returns a pointer to the leader. +// If hordeID is 0, it's randomly assigned based on the depth, with a 10% chance of an out-of-depth spawn from 1-5 +// levels deeper. If x is negative, location is random. Returns a pointer to the leader. creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFlags, unsigned long requiredFlags) { short i, failsafe, depth; const hordeType *theHorde; @@ -770,8 +716,7 @@ creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFla return NULL; } if (x >= 0 && y >= 0) { - if (cellHasTerrainFlag(x, y, T_PATHING_BLOCKER) - && (!hordeCatalog[hordeID].spawnsIn || !cellHasTerrainType(x, y, hordeCatalog[hordeID].spawnsIn))) { + if (cellHasTerrainFlag(x, y, T_PATHING_BLOCKER) && (!hordeCatalog[hordeID].spawnsIn || !cellHasTerrainType(x, y, hordeCatalog[hordeID].spawnsIn))) { // don't spawn a horde in special terrain unless it's meant to spawn there tryAgain = true; @@ -790,8 +735,7 @@ creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFla i = 0; do { pos loc; - while (!randomMatchingLocation(&loc.x, &loc.y, FLOOR, NOTHING, (hordeCatalog[hordeID].spawnsIn ? hordeCatalog[hordeID].spawnsIn : -1)) - || passableArcCount(loc.x, loc.y) > 1) { + while (!randomMatchingLocation(&loc.x, &loc.y, FLOOR, NOTHING, (hordeCatalog[hordeID].spawnsIn ? hordeCatalog[hordeID].spawnsIn : -1)) || passableArcCount(loc.x, loc.y) > 1) { if (!--failsafe) { return NULL; } @@ -811,9 +755,9 @@ creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFla } while (i < 25 && (pmap[x][y].flags & (ANY_KIND_OF_VISIBLE | IN_FIELD_OF_VIEW))); } -// if (hordeCatalog[hordeID].spawnsIn == DEEP_WATER && pmap[x][y].layers[LIQUID] != DEEP_WATER) { -// message("Waterborne monsters spawned on land!", REQUIRE_ACKNOWLEDGMENT); -// } + // if (hordeCatalog[hordeID].spawnsIn == DEEP_WATER && pmap[x][y].layers[LIQUID] != DEEP_WATER) { + // message("Waterborne monsters spawned on land!", REQUIRE_ACKNOWLEDGMENT); + // } theHorde = &hordeCatalog[hordeID]; @@ -851,7 +795,7 @@ creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFla fillGrid(leader->safetyMap, 0); } - preexistingMonst = monsterAtLoc((pos){ x, y }); + preexistingMonst = monsterAtLoc((pos){x, y}); if (preexistingMonst) { killCreature(preexistingMonst, true); // If there's already a monster here, quietly bury the body. } @@ -893,9 +837,7 @@ creatureIterator iterateCreatures(creatureList *list) { } return iter; } -boolean hasNextCreature(creatureIterator iter) { - return iter.next != NULL; -} +boolean hasNextCreature(creatureIterator iter) { return iter.next != NULL; } creature *nextCreature(creatureIterator *iter) { if (iter->next == NULL) { return NULL; @@ -969,7 +911,7 @@ boolean summonMinions(creature *summoner) { grid = allocGrid(); fillGrid(grid, 0); calculateDistances(grid, summoner->loc.x, summoner->loc.y, (T_PATHING_BLOCKER | T_SACRED), NULL, true, true); - findReplaceGrid(grid, 1, DCOLS/2, 1); + findReplaceGrid(grid, 1, DCOLS / 2, 1); findReplaceGrid(grid, 2, 30000, 0); getTerrainGrid(grid, 0, (T_PATHING_BLOCKER | T_HARMFUL_TERRAIN), (IN_FIELD_OF_VIEW | CLAIRVOYANT_VISIBLE | HAS_PLAYER | HAS_MONSTER)); } else { @@ -979,8 +921,7 @@ boolean summonMinions(creature *summoner) { creature *host = NULL; for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); - if (monst != summoner && monstersAreTeammates(monst, summoner) - && (monst->bookkeepingFlags & MB_JUST_SUMMONED)) { + if (monst != summoner && monstersAreTeammates(monst, summoner) && (monst->bookkeepingFlags & MB_JUST_SUMMONED)) { if (hordeCatalog[hordeID].flags & HORDE_SUMMONED_AT_DISTANCE) { x = y = -1; @@ -1048,7 +989,7 @@ void populateMonsters() { while (rand_percent(60)) { numberOfMonsters++; } - for (i=0; iloc.x, monst->loc.y, forbiddenFlagsForMonster(&(monst->info)) & T_DIVIDES_LEVEL, NULL, true, false); - findReplaceGrid(grid, -30000, DCOLS/2, 0); + findReplaceGrid(grid, -30000, DCOLS / 2, 0); findReplaceGrid(grid, 2, 30000, 1); if (validLocationCount(grid, 1) < 1) { fillGrid(grid, 1); @@ -1137,20 +1078,20 @@ void teleport(creature *monst, short x, short y, boolean respectTerrainAvoidance } else { getTerrainGrid(grid, 0, forbiddenFlagsForMonster(&(monst->info)), (IS_IN_MACHINE | HAS_PLAYER | HAS_MONSTER | HAS_STAIRS)); } - for (i=0; i= 0 - && wpIndex < rogue.wpCount - && !monst->waypointAlreadyVisited[wpIndex] - && rogue.wpDistance[wpIndex][monst->loc.x][monst->loc.y] >= 0 + return (wpIndex >= 0 && wpIndex < rogue.wpCount && !monst->waypointAlreadyVisited[wpIndex] && rogue.wpDistance[wpIndex][monst->loc.x][monst->loc.y] >= 0 && nextStep(rogue.wpDistance[wpIndex], monst->loc.x, monst->loc.y, monst, false) != NO_DIRECTION); } short closestWaypointIndex(creature *monst) { short i, closestDistance, closestIndex; - closestDistance = DCOLS/2; + closestDistance = DCOLS / 2; closestIndex = -1; - for (i=0; i < rogue.wpCount; i++) { - if (isValidWanderDestination(monst, i) - && rogue.wpDistance[i][monst->loc.x][monst->loc.y] < closestDistance) { + for (i = 0; i < rogue.wpCount; i++) { + if (isValidWanderDestination(monst, i) && rogue.wpDistance[i][monst->loc.x][monst->loc.y] < closestDistance) { closestDistance = rogue.wpDistance[i][monst->loc.x][monst->loc.y]; closestIndex = i; @@ -1204,7 +1141,7 @@ void chooseNewWanderDestination(creature *monst) { monst->targetWaypointIndex = closestWaypointIndex(monst); // Will be -1 if no waypoints were available. if (monst->targetWaypointIndex == -1) { - for (i=0; i < rogue.wpCount; i++) { + for (i = 0; i < rogue.wpCount; i++) { monst->waypointAlreadyVisited[i] = 0; } monst->targetWaypointIndex = closestWaypointIndex(monst); @@ -1279,15 +1216,13 @@ boolean monsterAvoids(creature *monst, pos p) { getLocationFlags(p.x, p.y, &tFlags, NULL, &cFlags, monst == &player); // everyone but the player avoids the stairs - if ((p.x == rogue.downLoc.x && p.y == rogue.downLoc.y) - || (p.x == rogue.upLoc.x && p.y == rogue.upLoc.y)) { + if ((p.x == rogue.downLoc.x && p.y == rogue.downLoc.y) || (p.x == rogue.upLoc.x && p.y == rogue.upLoc.y)) { return monst != &player; } // dry land - if (monst->info.flags & MONST_RESTRICTED_TO_LIQUID - && !cellHasTMFlag(p.x, p.y, TM_ALLOWS_SUBMERGING)) { + if (monst->info.flags & MONST_RESTRICTED_TO_LIQUID && !cellHasTMFlag(p.x, p.y, TM_ALLOWS_SUBMERGING)) { return true; } @@ -1298,16 +1233,13 @@ boolean monsterAvoids(creature *monst, pos p) { // walls if (tFlags & T_OBSTRUCTS_PASSABILITY) { - if (monst != &player - && cellHasTMFlag(p.x, p.y, TM_IS_SECRET) - && !(discoveredTerrainFlagsAtLoc(p.x, p.y) & avoidedFlagsForMonster(&(monst->info)))) { + if (monst != &player && cellHasTMFlag(p.x, p.y, TM_IS_SECRET) && !(discoveredTerrainFlagsAtLoc(p.x, p.y) & avoidedFlagsForMonster(&(monst->info)))) { // This is so monsters can use secret doors but won't embed themselves in secret levers. return false; } if (distanceBetween(monst->loc, p) <= 1) { defender = monsterAtLoc(p); - if (defender - && (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { + if (defender && (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { return false; } } @@ -1318,9 +1250,7 @@ boolean monsterAvoids(creature *monst, pos p) { // unless it is immune to us for whatever reason. if (distanceBetween(monst->loc, p) <= 1) { defender = monsterAtLoc(p); - if (defender - && !(defender->bookkeepingFlags & MB_IS_DYING) - && monsterWillAttackTarget(monst, defender)) { + if (defender && !(defender->bookkeepingFlags & MB_IS_DYING) && monsterWillAttackTarget(monst, defender)) { if (attackWouldBeFutile(monst, defender)) { return true; @@ -1332,10 +1262,7 @@ boolean monsterAvoids(creature *monst, pos p) { // Monsters always avoid enemy monsters that we can't damage. defender = monsterAtLoc(p); - if (defender - && !(defender->bookkeepingFlags & MB_IS_DYING) - && monstersAreEnemies(monst, defender) - && attackWouldBeFutile(monst, defender)) { + if (defender && !(defender->bookkeepingFlags & MB_IS_DYING) && monstersAreEnemies(monst, defender) && attackWouldBeFutile(monst, defender)) { return true; } @@ -1368,10 +1295,7 @@ boolean monsterAvoids(creature *monst, pos p) { if (monst == &player) { terrainImmunities |= T_SACRED; } - if (monst == &player - && rogue.armor - && (rogue.armor->flags & ITEM_RUNIC) - && rogue.armor->enchant2 == A_RESPIRATION) { + if (monst == &player && rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && rogue.armor->enchant2 == A_RESPIRATION) { terrainImmunities |= T_RESPIRATION_IMMUNITIES; } @@ -1382,90 +1306,65 @@ boolean monsterAvoids(creature *monst, pos p) { } // brimstone - if (!(monst->status[STATUS_IMMUNE_TO_FIRE]) - && !(monst->info.flags & MONST_INVULNERABLE) - && (tFlags & T_SPONTANEOUSLY_IGNITES) - && !(cFlags & (HAS_MONSTER | HAS_PLAYER)) - && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_IS_FIRE | T_SPONTANEOUSLY_IGNITES) - && (monst == &player || (monst->creatureState != MONSTER_TRACKING_SCENT && monst->creatureState != MONSTER_FLEEING))) { + if (!(monst->status[STATUS_IMMUNE_TO_FIRE]) && !(monst->info.flags & MONST_INVULNERABLE) && (tFlags & T_SPONTANEOUSLY_IGNITES) && !(cFlags & (HAS_MONSTER | HAS_PLAYER)) + && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_IS_FIRE | T_SPONTANEOUSLY_IGNITES) && (monst == &player || (monst->creatureState != MONSTER_TRACKING_SCENT && monst->creatureState != MONSTER_FLEEING))) { return true; } // burning wandering monsters avoid flammable terrain out of common courtesy - if (monst != &player - && monst->creatureState == MONSTER_WANDERING - && (monst->info.flags & MONST_FIERY) - && (tFlags & T_IS_FLAMMABLE)) { + if (monst != &player && monst->creatureState == MONSTER_WANDERING && (monst->info.flags & MONST_FIERY) && (tFlags & T_IS_FLAMMABLE)) { return true; } // burning monsters avoid explosive terrain and steam-emitting terrain - if (monst != &player - && monst->status[STATUS_BURNING] - && (burnedTerrainFlagsAtLoc(p.x, p.y) & (T_CAUSES_EXPLOSIVE_DAMAGE | T_CAUSES_DAMAGE | T_AUTO_DESCENT) & ~terrainImmunities)) { + if (monst != &player && monst->status[STATUS_BURNING] && (burnedTerrainFlagsAtLoc(p.x, p.y) & (T_CAUSES_EXPLOSIVE_DAMAGE | T_CAUSES_DAMAGE | T_AUTO_DESCENT) & ~terrainImmunities)) { return true; } // fire - if ((tFlags & T_IS_FIRE & ~terrainImmunities) - && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_IS_FIRE) - && !(cFlags & (HAS_MONSTER | HAS_PLAYER)) + if ((tFlags & T_IS_FIRE & ~terrainImmunities) && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_IS_FIRE) && !(cFlags & (HAS_MONSTER | HAS_PLAYER)) && (monst != &player || rogue.mapToShore[p.x][p.y] >= player.status[STATUS_IMMUNE_TO_FIRE])) { return true; } // non-fire harmful terrain - if ((tFlags & T_HARMFUL_TERRAIN & ~T_IS_FIRE & ~terrainImmunities) - && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, (T_HARMFUL_TERRAIN & ~T_IS_FIRE))) { + if ((tFlags & T_HARMFUL_TERRAIN & ~T_IS_FIRE & ~terrainImmunities) && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, (T_HARMFUL_TERRAIN & ~T_IS_FIRE))) { return true; } // chasms or trap doors - if ((tFlags & T_AUTO_DESCENT & ~terrainImmunities) - && (!(tFlags & T_ENTANGLES) || !(monst->info.flags & MONST_IMMUNE_TO_WEBS))) { + if ((tFlags & T_AUTO_DESCENT & ~terrainImmunities) && (!(tFlags & T_ENTANGLES) || !(monst->info.flags & MONST_IMMUNE_TO_WEBS))) { return true; } // gas or other environmental traps - if ((tFlags & T_IS_DF_TRAP & ~terrainImmunities) - && !(cFlags & PRESSURE_PLATE_DEPRESSED) - && (monst == &player || monst->creatureState == MONSTER_WANDERING - || (monst->creatureState == MONSTER_ALLY && !(cellHasTMFlag(p.x, p.y, TM_IS_SECRET)))) - && !(monst->status[STATUS_ENTRANCED]) + if ((tFlags & T_IS_DF_TRAP & ~terrainImmunities) && !(cFlags & PRESSURE_PLATE_DEPRESSED) + && (monst == &player || monst->creatureState == MONSTER_WANDERING || (monst->creatureState == MONSTER_ALLY && !(cellHasTMFlag(p.x, p.y, TM_IS_SECRET)))) && !(monst->status[STATUS_ENTRANCED]) && (!(tFlags & T_ENTANGLES) || !(monst->info.flags & MONST_IMMUNE_TO_WEBS))) { return true; } // lava - if ((tFlags & T_LAVA_INSTA_DEATH & ~terrainImmunities) - && (!(tFlags & T_ENTANGLES) || !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) + if ((tFlags & T_LAVA_INSTA_DEATH & ~terrainImmunities) && (!(tFlags & T_ENTANGLES) || !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) && (monst != &player || rogue.mapToShore[p.x][p.y] >= max(player.status[STATUS_IMMUNE_TO_FIRE], player.status[STATUS_LEVITATING]))) { return true; } // deep water - if ((tFlags & T_IS_DEEP_WATER & ~terrainImmunities) - && (!(tFlags & T_ENTANGLES) || !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) - && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_IS_DEEP_WATER)) { + if ((tFlags & T_IS_DEEP_WATER & ~terrainImmunities) && (!(tFlags & T_ENTANGLES) || !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_IS_DEEP_WATER)) { return true; // avoid only if not already in it } // poisonous lichen - if ((tFlags & T_CAUSES_POISON & ~terrainImmunities) - && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_CAUSES_POISON) - && (monst == &player || monst->creatureState != MONSTER_TRACKING_SCENT || monst->currentHP < 10)) { + if ((tFlags & T_CAUSES_POISON & ~terrainImmunities) && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_CAUSES_POISON) && (monst == &player || monst->creatureState != MONSTER_TRACKING_SCENT || monst->currentHP < 10)) { return true; } // Smart monsters don't attack in corridors if they belong to a group and they can help it. - if ((monst->info.abilityFlags & MA_AVOID_CORRIDORS) - && !(monst->status[STATUS_ENRAGED] && monst->currentHP <= monst->info.maxHP / 2) - && monst->creatureState == MONSTER_TRACKING_SCENT - && (monst->bookkeepingFlags & (MB_FOLLOWER | MB_LEADER)) - && passableArcCount(p.x, p.y) >= 2 - && passableArcCount(monst->loc.x, monst->loc.y) < 2 + if ((monst->info.abilityFlags & MA_AVOID_CORRIDORS) && !(monst->status[STATUS_ENRAGED] && monst->currentHP <= monst->info.maxHP / 2) && monst->creatureState == MONSTER_TRACKING_SCENT + && (monst->bookkeepingFlags & (MB_FOLLOWER | MB_LEADER)) && passableArcCount(p.x, p.y) >= 2 && passableArcCount(monst->loc.x, monst->loc.y) < 2 && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, (T_HARMFUL_TERRAIN & ~terrainImmunities))) { return true; } @@ -1508,14 +1407,14 @@ boolean moveMonsterPassivelyTowards(creature *monst, pos targetLoc, boolean will // If they all fail, return false. if (monsterAvoids(monst, (pos){newX, newY}) || (!willingToAttackPlayer && (pmap[newX][newY].flags & HAS_PLAYER)) || !moveMonster(monst, dx, dy)) { if (distanceBetween((pos){x, y}, targetLoc) <= 1 && (dx == 0 || dy == 0)) { // cardinally adjacent - return false; // destination is blocked + return false; // destination is blocked } - //abs(targetLoc.x - x) < abs(targetLoc.y - y) + // abs(targetLoc.x - x) < abs(targetLoc.y - y) if ((max(targetLoc.x, x) - min(targetLoc.x, x)) < (max(targetLoc.y, y) - min(targetLoc.y, y))) { if (monsterAvoids(monst, (pos){x, newY}) || (!willingToAttackPlayer && pmap[x][newY].flags & HAS_PLAYER) || !moveMonster(monst, 0, dy)) { - if (monsterAvoids(monst, (pos){newX, y}) || (!willingToAttackPlayer && pmap[newX][y].flags & HAS_PLAYER) || !moveMonster(monst, dx, 0)) { - if (monsterAvoids(monst, (pos){x-1, newY}) || (!willingToAttackPlayer && pmap[x-1][newY].flags & HAS_PLAYER) || !moveMonster(monst, -1, dy)) { - if (monsterAvoids(monst, (pos){x+1, newY}) || (!willingToAttackPlayer && pmap[x+1][newY].flags & HAS_PLAYER) || !moveMonster(monst, 1, dy)) { + if (monsterAvoids(monst, (pos){newX, y}) || (!willingToAttackPlayer && pmap[newX][y].flags & HAS_PLAYER) || !moveMonster(monst, dx, 0)) { + if (monsterAvoids(monst, (pos){x - 1, newY}) || (!willingToAttackPlayer && pmap[x - 1][newY].flags & HAS_PLAYER) || !moveMonster(monst, -1, dy)) { + if (monsterAvoids(monst, (pos){x + 1, newY}) || (!willingToAttackPlayer && pmap[x + 1][newY].flags & HAS_PLAYER) || !moveMonster(monst, 1, dy)) { return false; } } @@ -1524,8 +1423,8 @@ boolean moveMonsterPassivelyTowards(creature *monst, pos targetLoc, boolean will } else { if (monsterAvoids(monst, (pos){newX, y}) || (!willingToAttackPlayer && pmap[newX][y].flags & HAS_PLAYER) || !moveMonster(monst, dx, 0)) { if (monsterAvoids(monst, (pos){x, newY}) || (!willingToAttackPlayer && pmap[x][newY].flags & HAS_PLAYER) || !moveMonster(monst, 0, dy)) { - if (monsterAvoids(monst, (pos){newX, y-1}) || (!willingToAttackPlayer && pmap[newX][y-1].flags & HAS_PLAYER) || !moveMonster(monst, dx, -1)) { - if (monsterAvoids(monst, (pos){newX, y+1}) || (!willingToAttackPlayer && pmap[newX][y+1].flags & HAS_PLAYER) || !moveMonster(monst, dx, 1)) { + if (monsterAvoids(monst, (pos){newX, y - 1}) || (!willingToAttackPlayer && pmap[newX][y - 1].flags & HAS_PLAYER) || !moveMonster(monst, dx, -1)) { + if (monsterAvoids(monst, (pos){newX, y + 1}) || (!willingToAttackPlayer && pmap[newX][y + 1].flags & HAS_PLAYER) || !moveMonster(monst, dx, 1)) { return false; } } @@ -1536,9 +1435,7 @@ boolean moveMonsterPassivelyTowards(creature *monst, pos targetLoc, boolean will return true; } -short distanceBetween(pos loc1, pos loc2) { - return max(abs(loc1.x - loc2.x), abs(loc1.y - loc2.y)); -} +short distanceBetween(pos loc1, pos loc2) { return max(abs(loc1.x - loc2.x), abs(loc1.y - loc2.y)); } void alertMonster(creature *monst) { monst->creatureState = (monst->creatureMode == MODE_PERM_FLEEING ? MONSTER_FLEEING : MONSTER_TRACKING_SCENT); @@ -1553,13 +1450,11 @@ void wakeUp(creature *monst) { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *teammate = nextCreature(&it); if (monst != teammate && monstersAreTeammates(monst, teammate) && teammate->creatureMode == MODE_NORMAL) { - if (teammate->creatureState == MONSTER_SLEEPING - || teammate->creatureState == MONSTER_WANDERING) { + if (teammate->creatureState == MONSTER_SLEEPING || teammate->creatureState == MONSTER_WANDERING) { teammate->ticksUntilTurn = max(100, teammate->ticksUntilTurn); } if (monst->creatureState != MONSTER_ALLY) { - teammate->creatureState = - (teammate->creatureMode == MODE_PERM_FLEEING ? MONSTER_FLEEING : MONSTER_TRACKING_SCENT); + teammate->creatureState = (teammate->creatureMode == MODE_PERM_FLEEING ? MONSTER_FLEEING : MONSTER_TRACKING_SCENT); updateMonsterState(teammate); } } @@ -1568,7 +1463,7 @@ void wakeUp(creature *monst) { boolean monsterCanShootWebs(creature *monst) { short i; - for (i=0; monst->info.bolts[i] != 0; i++) { + for (i = 0; monst->info.bolts[i] != 0; i++) { const bolt *theBolt = &boltCatalog[monst->info.bolts[i]]; if (theBolt->pathDF && (tileCatalog[dungeonFeatureCatalog[theBolt->pathDF].tile].flags & T_ENTANGLES)) { return true; @@ -1591,8 +1486,7 @@ short awarenessDistance(creature *observer, creature *target) { // to guide them, but only as long as the player is within FOV. After that, we switch to wandering // and wander toward the last location that we saw the player. perceivedDistance = (rogue.scentTurnNumber - scentMap[observer->loc.x][observer->loc.y]); // this value is double the apparent distance - if ((target == &player && (pmapAt(observer->loc)->flags & IN_FIELD_OF_VIEW)) - || (target != &player && openPathBetween(observer->loc.x, observer->loc.y, target->loc.x, target->loc.y))) { + if ((target == &player && (pmapAt(observer->loc)->flags & IN_FIELD_OF_VIEW)) || (target != &player && openPathBetween(observer->loc.x, observer->loc.y, target->loc.x, target->loc.y))) { perceivedDistance = min(perceivedDistance, scentDistance(observer->loc.x, observer->loc.y, target->loc.x, target->loc.y)); } @@ -1602,7 +1496,7 @@ short awarenessDistance(creature *observer, creature *target) { if (perceivedDistance < 0) { perceivedDistance = 1000; } - return ((short) perceivedDistance); + return ((short)perceivedDistance); } // yes or no -- observer is aware of the target as of this new turn. @@ -1625,13 +1519,12 @@ boolean awareOfTarget(creature *observer, creature *target) { retval = false; } else if (observer->creatureState == MONSTER_TRACKING_SCENT) { // already aware of the target, lose track 3% of the time if outside of stealth range. - if (perceivedDistance > awareness) { - retval = rand_percent(97); - } else { + if (perceivedDistance > awareness) { + retval = rand_percent(97); + } else { retval = true; - } - } else if (target == &player - && !(pmapAt(observer->loc)->flags & IN_FIELD_OF_VIEW)) { + } + } else if (target == &player && !(pmapAt(observer->loc)->flags & IN_FIELD_OF_VIEW)) { // observer not hunting and player-target not in field of view retval = false; } else if (perceivedDistance <= awareness) { @@ -1648,7 +1541,7 @@ short closestWaypointIndexTo(pos p) { closestDistance = 1000; closestIndex = -1; - for (i=0; i < rogue.wpCount; i++) { + for (i = 0; i < rogue.wpCount; i++) { if (rogue.wpDistance[i][p.x][p.y] < closestDistance) { closestDistance = rogue.wpDistance[i][p.x][p.y]; closestIndex = i; @@ -1674,8 +1567,7 @@ void updateMonsterState(creature *monst) { x = monst->loc.x; y = monst->loc.y; - if ((monst->info.flags & MONST_ALWAYS_HUNTING) - && monst->creatureState != MONSTER_ALLY) { + if ((monst->info.flags & MONST_ALWAYS_HUNTING) && monst->creatureState != MONSTER_ALLY) { monst->creatureState = MONSTER_TRACKING_SCENT; return; @@ -1683,8 +1575,7 @@ void updateMonsterState(creature *monst) { awareOfPlayer = awareOfTarget(monst, &player); - if ((monst->info.flags & MONST_IMMOBILE) - && monst->creatureState != MONSTER_ALLY) { + if ((monst->info.flags & MONST_IMMOBILE) && monst->creatureState != MONSTER_ALLY) { if (awareOfPlayer) { monst->creatureState = MONSTER_TRACKING_SCENT; @@ -1694,30 +1585,24 @@ void updateMonsterState(creature *monst) { return; } - if (monst->creatureMode == MODE_PERM_FLEEING - && (monst->creatureState == MONSTER_WANDERING || monst->creatureState == MONSTER_TRACKING_SCENT)) { + if (monst->creatureMode == MODE_PERM_FLEEING && (monst->creatureState == MONSTER_WANDERING || monst->creatureState == MONSTER_TRACKING_SCENT)) { monst->creatureState = MONSTER_FLEEING; } - closestFearedEnemy = DCOLS+DROWS; + closestFearedEnemy = DCOLS + DROWS; boolean handledPlayer = false; for (creatureIterator it = iterateCreatures(monsters); !handledPlayer || hasNextCreature(it);) { creature *monst2 = !handledPlayer ? &player : nextCreature(&it); handledPlayer = true; - if (monsterFleesFrom(monst, monst2) - && distanceBetween((pos){x, y}, monst2->loc) < closestFearedEnemy - && traversiblePathBetween(monst2, x, y) - && openPathBetween(x, y, monst2->loc.x, monst2->loc.y)) { + if (monsterFleesFrom(monst, monst2) && distanceBetween((pos){x, y}, monst2->loc) < closestFearedEnemy && traversiblePathBetween(monst2, x, y) && openPathBetween(x, y, monst2->loc.x, monst2->loc.y)) { closestFearedEnemy = distanceBetween((pos){x, y}, monst2->loc); } } - if ((monst->creatureState == MONSTER_WANDERING) - && awareOfPlayer - && (pmapAt(player.loc)->flags & IN_FIELD_OF_VIEW)) { + if ((monst->creatureState == MONSTER_WANDERING) && awareOfPlayer && (pmapAt(player.loc)->flags & IN_FIELD_OF_VIEW)) { // If wandering and you notice the player, start tracking the scent. alertMonster(monst); } else if (monst->creatureState == MONSTER_SLEEPING) { @@ -1729,43 +1614,29 @@ void updateMonsterState(creature *monst) { // if tracking scent, but the scent is weaker than the scent detection threshold, begin wandering. monst->creatureState = MONSTER_WANDERING; wanderToward(monst, monst->lastSeenPlayerAt); - } else if (monst->creatureState == MONSTER_TRACKING_SCENT - && closestFearedEnemy < 3) { + } else if (monst->creatureState == MONSTER_TRACKING_SCENT && closestFearedEnemy < 3) { monst->creatureState = MONSTER_FLEEING; - } else if (monst->creatureState != MONSTER_ALLY - && (monst->info.flags & MONST_FLEES_NEAR_DEATH) - && monst->currentHP <= 3 * monst->info.maxHP / 4) { + } else if (monst->creatureState != MONSTER_ALLY && (monst->info.flags & MONST_FLEES_NEAR_DEATH) && monst->currentHP <= 3 * monst->info.maxHP / 4) { - if (monst->creatureState == MONSTER_FLEEING - || monst->currentHP <= monst->info.maxHP / 4) { + if (monst->creatureState == MONSTER_FLEEING || monst->currentHP <= monst->info.maxHP / 4) { monst->creatureState = MONSTER_FLEEING; } - } else if (monst->creatureMode == MODE_NORMAL - && monst->creatureState == MONSTER_FLEEING - && !(monst->status[STATUS_MAGICAL_FEAR]) - && closestFearedEnemy >= 3) { + } else if (monst->creatureMode == MODE_NORMAL && monst->creatureState == MONSTER_FLEEING && !(monst->status[STATUS_MAGICAL_FEAR]) && closestFearedEnemy >= 3) { monst->creatureState = MONSTER_TRACKING_SCENT; - } else if (monst->creatureMode == MODE_PERM_FLEEING - && monst->creatureState == MONSTER_FLEEING - && (monst->info.abilityFlags & MA_HIT_STEAL_FLEE) - && !(monst->status[STATUS_MAGICAL_FEAR]) - && !(monst->carriedItem)) { + } else if (monst->creatureMode == MODE_PERM_FLEEING && monst->creatureState == MONSTER_FLEEING && (monst->info.abilityFlags & MA_HIT_STEAL_FLEE) && !(monst->status[STATUS_MAGICAL_FEAR]) && !(monst->carriedItem)) { monst->creatureMode = MODE_NORMAL; if (monst->leader == &player) { - monst->creatureState = MONSTER_ALLY; // Reset state if a discorded ally steals an item and then loses it (probably in deep water) + monst->creatureState = MONSTER_ALLY; // Reset state if a discorded ally steals an item and then loses it + // (probably in deep water) } else { alertMonster(monst); } - } else if (monst->creatureMode == MODE_NORMAL - && monst->creatureState == MONSTER_FLEEING - && (monst->info.flags & MONST_FLEES_NEAR_DEATH) - && !(monst->status[STATUS_MAGICAL_FEAR]) - && monst->currentHP >= monst->info.maxHP * 3 / 4) { + } else if (monst->creatureMode == MODE_NORMAL && monst->creatureState == MONSTER_FLEEING && (monst->info.flags & MONST_FLEES_NEAR_DEATH) && !(monst->status[STATUS_MAGICAL_FEAR]) && monst->currentHP >= monst->info.maxHP * 3 / 4) { if ((monst->bookkeepingFlags & MB_FOLLOWER) && monst->leader == &player) { monst->creatureState = MONSTER_ALLY; @@ -1775,8 +1646,7 @@ void updateMonsterState(creature *monst) { } if (awareOfPlayer) { - if (monst->creatureState == MONSTER_FLEEING - || monst->creatureState == MONSTER_TRACKING_SCENT) { + if (monst->creatureState == MONSTER_FLEEING || monst->creatureState == MONSTER_TRACKING_SCENT) { monst->lastSeenPlayerAt = player.loc; } @@ -1789,9 +1659,7 @@ void decrementMonsterStatus(creature *monst) { monst->bookkeepingFlags &= ~MB_JUST_SUMMONED; - if (monst->currentHP < monst->info.maxHP - && monst->info.turnsBetweenRegen > 0 - && !monst->status[STATUS_POISONED]) { + if (monst->currentHP < monst->info.maxHP && monst->info.turnsBetweenRegen > 0 && !monst->status[STATUS_POISONED]) { if ((monst->turnsUntilRegen -= 1000) <= 0) { monst->currentHP++; @@ -1800,7 +1668,7 @@ void decrementMonsterStatus(creature *monst) { } } - for (i=0; istatus[i] && !(monst->info.flags & MONST_FLIES)) { @@ -1832,15 +1700,11 @@ void decrementMonsterStatus(creature *monst) { monst->status[i]--; } damage = rand_range(1, 3); - if (!(monst->status[STATUS_IMMUNE_TO_FIRE]) - && !(monst->info.flags & MONST_INVULNERABLE) - && inflictDamage(NULL, monst, damage, &orange, true)) { + if (!(monst->status[STATUS_IMMUNE_TO_FIRE]) && !(monst->info.flags & MONST_INVULNERABLE) && inflictDamage(NULL, monst, damage, &orange, true)) { if (canSeeMonster(monst)) { monsterName(buf, monst, true); - sprintf(buf2, "%s burns %s.", - buf, - (monst->info.flags & MONST_INANIMATE) ? "up" : "to death"); + sprintf(buf2, "%s burns %s.", buf, (monst->info.flags & MONST_INANIMATE) ? "up" : "to death"); messageWithColor(buf2, messageColorFromVictim(monst), 0); } killCreature(monst, false); @@ -1889,9 +1753,7 @@ void decrementMonsterStatus(creature *monst) { break; case STATUS_DISCORDANT: if (monst->status[i] && !--monst->status[i]) { - if (monst->creatureState == MONSTER_FLEEING - && !monst->status[STATUS_MAGICAL_FEAR] - && monst->leader == &player) { + if (monst->creatureState == MONSTER_FLEEING && !monst->status[STATUS_MAGICAL_FEAR] && monst->leader == &player) { monst->creatureState = MONSTER_ALLY; if (monst->carriedItem) { @@ -1919,10 +1781,7 @@ void decrementMonsterStatus(creature *monst) { } break; case STATUS_INVISIBLE: - if (monst->status[i] - && !(monst->info.flags & MONST_INVISIBLE) - && !--monst->status[i] - && playerCanSee(monst->loc.x, monst->loc.y)) { + if (monst->status[i] && !(monst->info.flags & MONST_INVISIBLE) && !--monst->status[i] && playerCanSee(monst->loc.x, monst->loc.y)) { refreshDungeonCell(monst->loc.x, monst->loc.y); } @@ -1938,15 +1797,12 @@ void decrementMonsterStatus(creature *monst) { if (monsterCanSubmergeNow(monst) && !(monst->bookkeepingFlags & MB_SUBMERGED)) { if (rand_percent(20)) { monst->bookkeepingFlags |= MB_SUBMERGED; - if (!monst->status[STATUS_MAGICAL_FEAR] - && monst->creatureState == MONSTER_FLEEING - && (!(monst->info.flags & MONST_FLEES_NEAR_DEATH) || monst->currentHP >= monst->info.maxHP * 3 / 4)) { + if (!monst->status[STATUS_MAGICAL_FEAR] && monst->creatureState == MONSTER_FLEEING && (!(monst->info.flags & MONST_FLEES_NEAR_DEATH) || monst->currentHP >= monst->info.maxHP * 3 / 4)) { monst->creatureState = MONSTER_TRACKING_SCENT; } refreshDungeonCell(monst->loc.x, monst->loc.y); - } else if (monst->info.flags & (MONST_RESTRICTED_TO_LIQUID) - && monst->creatureState != MONSTER_ALLY) { + } else if (monst->info.flags & (MONST_RESTRICTED_TO_LIQUID) && monst->creatureState != MONSTER_ALLY) { monst->creatureState = MONSTER_FLEEING; } } @@ -1954,13 +1810,13 @@ void decrementMonsterStatus(creature *monst) { boolean traversiblePathBetween(creature *monst, short x2, short y2) { pos originLoc = monst->loc; - pos targetLoc = (pos){ .x = x2, .y = y2 }; + pos targetLoc = (pos){.x = x2, .y = y2}; // Using BOLT_NONE here to favor a path that avoids obstacles to one that hits them pos coords[DCOLS]; int n = getLineCoordinates(coords, originLoc, targetLoc, &boltCatalog[BOLT_NONE]); - for (int i=0; iinfo.bolts[i] != 0; i++) { + for (i = 0; monst->info.bolts[i] != 0; i++) { if (boltCatalog[monst->info.bolts[i]].boltEffect == boltEffectIndex) { return monst->info.bolts[i]; } @@ -2075,8 +1930,7 @@ void pathTowardCreature(creature *monst, creature *target) { } // blink to the target? - if (distanceBetween(monst->loc, target->loc) > 10 - || monstersAreEnemies(monst, target)) { + if (distanceBetween(monst->loc, target->loc) > 10 || monstersAreEnemies(monst, target)) { if (monsterBlinkToPreferenceMap(monst, target->mapToMe, false)) { // if it blinked monst->ticksUntilTurn = monst->attackSpeed * (monst->info.flags & MONST_CAST_SPELLS_SLOWLY ? 2 : 1); @@ -2098,20 +1952,12 @@ void pathTowardCreature(creature *monst, creature *target) { } boolean creatureEligibleForSwarming(creature *monst) { - if ((monst->info.flags & (MONST_IMMOBILE | MONST_GETS_TURN_ON_ACTIVATION | MONST_MAINTAINS_DISTANCE)) - || monst->status[STATUS_ENTRANCED] - || monst->status[STATUS_CONFUSED] - || monst->status[STATUS_STUCK] - || monst->status[STATUS_PARALYZED] - || monst->status[STATUS_MAGICAL_FEAR] - || monst->status[STATUS_LIFESPAN_REMAINING] == 1 - || (monst->bookkeepingFlags & (MB_SEIZED | MB_SEIZING))) { + if ((monst->info.flags & (MONST_IMMOBILE | MONST_GETS_TURN_ON_ACTIVATION | MONST_MAINTAINS_DISTANCE)) || monst->status[STATUS_ENTRANCED] || monst->status[STATUS_CONFUSED] || monst->status[STATUS_STUCK] || monst->status[STATUS_PARALYZED] + || monst->status[STATUS_MAGICAL_FEAR] || monst->status[STATUS_LIFESPAN_REMAINING] == 1 || (monst->bookkeepingFlags & (MB_SEIZED | MB_SEIZING))) { return false; } - if (monst != &player - && monst->creatureState != MONSTER_ALLY - && monst->creatureState != MONSTER_TRACKING_SCENT) { + if (monst != &player && monst->creatureState != MONSTER_ALLY && monst->creatureState != MONSTER_TRACKING_SCENT) { return false; } @@ -2132,9 +1978,7 @@ enum directions monsterSwarmDirection(creature *monst, creature *enemy) { return NO_DIRECTION; } - if (distanceBetween(monst->loc, enemy->loc) != 1 - || (diagonalBlocked(monst->loc.x, monst->loc.y, enemy->loc.x, enemy->loc.y, false) || (enemy->info.flags & MONST_ATTACKABLE_THRU_WALLS)) - || !monstersAreEnemies(monst, enemy)) { + if (distanceBetween(monst->loc, enemy->loc) != 1 || (diagonalBlocked(monst->loc.x, monst->loc.y, enemy->loc.x, enemy->loc.y, false) || (enemy->info.flags & MONST_ATTACKABLE_THRU_WALLS)) || !monstersAreEnemies(monst, enemy)) { return NO_DIRECTION; // Too far from the enemy, diagonally blocked, or not enemies with it. } @@ -2143,15 +1987,11 @@ enum directions monsterSwarmDirection(creature *monst, creature *enemy) { targetDir = NO_DIRECTION; shuffleList(dirList, 4); shuffleList(&(dirList[4]), 4); - for (int i=0; i<8 && targetDir == NO_DIRECTION; i++) { + for (int i = 0; i < 8 && targetDir == NO_DIRECTION; i++) { dir = dirList[i]; const pos newLoc = posNeighborInDirection(monst->loc, dir); - if (isPosInMap(newLoc) - && distanceBetween(enemy->loc, newLoc) == 1 - && !(pmapAt(newLoc)->flags & (HAS_PLAYER | HAS_MONSTER)) - && !diagonalBlocked(monst->loc.x, monst->loc.y, newLoc.x, newLoc.y, false) - && (!diagonalBlocked(enemy->loc.x, enemy->loc.y, newLoc.x, newLoc.y, false) || (enemy->info.flags & MONST_ATTACKABLE_THRU_WALLS)) - && !monsterAvoids(monst, newLoc)) { + if (isPosInMap(newLoc) && distanceBetween(enemy->loc, newLoc) == 1 && !(pmapAt(newLoc)->flags & (HAS_PLAYER | HAS_MONSTER)) && !diagonalBlocked(monst->loc.x, monst->loc.y, newLoc.x, newLoc.y, false) + && (!diagonalBlocked(enemy->loc.x, enemy->loc.y, newLoc.x, newLoc.y, false) || (enemy->info.flags & MONST_ATTACKABLE_THRU_WALLS)) && !monsterAvoids(monst, newLoc)) { targetDir = dir; } @@ -2166,27 +2006,18 @@ enum directions monsterSwarmDirection(creature *monst, creature *enemy) { for (creatureIterator it = iterateCreatures(monsters); !handledPlayer || hasNextCreature(it);) { creature *ally = !handledPlayer ? &player : nextCreature(&it); handledPlayer = true; - if (ally != monst - && ally != enemy - && monstersAreTeammates(monst, ally) - && monstersAreEnemies(ally, enemy) - && creatureEligibleForSwarming(ally) - && distanceBetween(monst->loc, ally->loc) == 1 - && !diagonalBlocked(monst->loc.x, monst->loc.y, ally->loc.x, ally->loc.y, false) - && !monsterAvoids(ally, monst->loc) + if (ally != monst && ally != enemy && monstersAreTeammates(monst, ally) && monstersAreEnemies(ally, enemy) && creatureEligibleForSwarming(ally) && distanceBetween(monst->loc, ally->loc) == 1 + && !diagonalBlocked(monst->loc.x, monst->loc.y, ally->loc.x, ally->loc.y, false) && !monsterAvoids(ally, monst->loc) && (distanceBetween(enemy->loc, ally->loc) > 1 || diagonalBlocked(enemy->loc.x, enemy->loc.y, ally->loc.x, ally->loc.y, false))) { // Found a prospective ally. - // Check that there isn't already an open space from which to attack the enemy that is accessible to the ally. + // Check that there isn't already an open space from which to attack the enemy that is accessible to the + // ally. alternateDirectionExists = false; - for (dir=0; dir< DIRECTION_COUNT && !alternateDirectionExists; dir++) { + for (dir = 0; dir < DIRECTION_COUNT && !alternateDirectionExists; dir++) { const pos newPos = posNeighborInDirection(ally->loc, dir); - if (isPosInMap(newPos) - && !(pmapAt(newPos)->flags & (HAS_PLAYER | HAS_MONSTER)) - && distanceBetween(enemy->loc, newPos) == 1 - && !diagonalBlocked(enemy->loc.x, enemy->loc.y, newPos.x, newPos.y, false) - && !diagonalBlocked(ally->loc.x, ally->loc.y, newPos.x, newPos.y, false) - && !monsterAvoids(ally, newPos)) { + if (isPosInMap(newPos) && !(pmapAt(newPos)->flags & (HAS_PLAYER | HAS_MONSTER)) && distanceBetween(enemy->loc, newPos) == 1 && !diagonalBlocked(enemy->loc.x, enemy->loc.y, newPos.x, newPos.y, false) + && !diagonalBlocked(ally->loc.x, ally->loc.y, newPos.x, newPos.y, false) && !monsterAvoids(ally, newPos)) { alternateDirectionExists = true; } @@ -2199,11 +2030,7 @@ enum directions monsterSwarmDirection(creature *monst, creature *enemy) { for (creatureIterator it2 = iterateCreatures(monsters); !handledPlayer || hasNextCreature(it2);) { creature *otherEnemy = !handledPlayer ? &player : nextCreature(&it2); handledPlayer = true; - if (ally != otherEnemy - && monst != otherEnemy - && enemy != otherEnemy - && monstersAreEnemies(ally, otherEnemy) - && distanceBetween(ally->loc, otherEnemy->loc) == 1 + if (ally != otherEnemy && monst != otherEnemy && enemy != otherEnemy && monstersAreEnemies(ally, otherEnemy) && distanceBetween(ally->loc, otherEnemy->loc) == 1 && (!diagonalBlocked(ally->loc.x, ally->loc.y, otherEnemy->loc.x, otherEnemy->loc.y, false) || (otherEnemy->info.flags & MONST_ATTACKABLE_THRU_WALLS))) { foundConflict = true; @@ -2224,29 +2051,17 @@ enum directions monsterSwarmDirection(creature *monst, creature *enemy) { // This is used as the sample space for bolt target coordinates, e.g. when reflecting or when // monsters are deciding where to blink. pos perimeterCoords(short n) { - if (n <= 10) { // top edge, left to right - return (pos){ - .x = n - 5, - .y = -5 - }; - } else if (n <= 21) { // bottom edge, left to right - return (pos){ - .x = (n - 11) - 5, - .y = 5 - }; - } else if (n <= 30) { // left edge, top to bottom - return (pos){ - .x = -5, - .y = (n - 22) - 4 - }; - } else if (n <= 39) { // right edge, top to bottom - return (pos){ - .x = 5, - .y = (n - 31) - 4 - }; + if (n <= 10) { // top edge, left to right + return (pos){.x = n - 5, .y = -5}; + } else if (n <= 21) { // bottom edge, left to right + return (pos){.x = (n - 11) - 5, .y = 5}; + } else if (n <= 30) { // left edge, top to bottom + return (pos){.x = -5, .y = (n - 22) - 4}; + } else if (n <= 39) { // right edge, top to bottom + return (pos){.x = 5, .y = (n - 31) - 4}; } else { message("ERROR! Bad perimeter coordinate request!", REQUIRE_ACKNOWLEDGMENT); - return (pos){ .x = 0, .y = 0 }; // garbage in, garbage out + return (pos){.x = 0, .y = 0}; // garbage in, garbage out } } @@ -2270,7 +2085,7 @@ boolean monsterBlinkToPreferenceMap(creature *monst, short **preferenceMap, bool gotOne = false; pos origin = monst->loc; - pos bestTarget = (pos){ .x = 0, .y = 0 }; + pos bestTarget = (pos){.x = 0, .y = 0}; short bestPreference = preferenceMap[monst->loc.x][monst->loc.y]; // make sure that we beat the four cardinal neighbors @@ -2278,14 +2093,13 @@ boolean monsterBlinkToPreferenceMap(creature *monst, short **preferenceMap, bool const pos monstNeighborLoc = posNeighborInDirection(monst->loc, i); nowPreference = preferenceMap[monstNeighborLoc.x][monstNeighborLoc.y]; - if (((blinkUphill && nowPreference > bestPreference) || (!blinkUphill && nowPreference < bestPreference)) - && !monsterAvoids(monst, monstNeighborLoc)) { + if (((blinkUphill && nowPreference > bestPreference) || (!blinkUphill && nowPreference < bestPreference)) && !monsterAvoids(monst, monstNeighborLoc)) { bestPreference = nowPreference; } } - for (i=0; i<40; i++) { + for (i = 0; i < 40; i++) { pos target = perimeterCoords(i); target.x += monst->loc.x; target.y += monst->loc.y; @@ -2294,17 +2108,14 @@ boolean monsterBlinkToPreferenceMap(creature *monst, short **preferenceMap, bool getImpactLoc(&impact, origin, target, maxDistance, true, &boltCatalog[BOLT_BLINKING]); nowPreference = preferenceMap[impact.x][impact.y]; - if (((blinkUphill && (nowPreference > bestPreference)) - || (!blinkUphill && (nowPreference < bestPreference))) - && !monsterAvoids(monst, impact)) { + if (((blinkUphill && (nowPreference > bestPreference)) || (!blinkUphill && (nowPreference < bestPreference))) && !monsterAvoids(monst, impact)) { bestTarget = target; - bestPreference = nowPreference; + bestPreference = nowPreference; if ((abs(impact.x - origin.x) > 1 || abs(impact.y - origin.y) > 1) // Note: these are deliberately backwards: - || (cellHasTerrainFlag(impact.x, origin.y, T_OBSTRUCTS_PASSABILITY)) - || (cellHasTerrainFlag(origin.x, impact.y, T_OBSTRUCTS_PASSABILITY))) { + || (cellHasTerrainFlag(impact.x, origin.y, T_OBSTRUCTS_PASSABILITY)) || (cellHasTerrainFlag(origin.x, impact.y, T_OBSTRUCTS_PASSABILITY))) { gotOne = true; } else { gotOne = false; @@ -2413,8 +2224,7 @@ boolean monsterSummons(creature *monst, boolean alwaysUse) { summonMinions(monst); return true; } - } else if ((monst->creatureState != MONSTER_ALLY || minionCount < 5) - && !rand_range(0, minionCount * minionCount * 3 + 1)) { + } else if ((monst->creatureState != MONSTER_ALLY || minionCount < 5) && !rand_range(0, minionCount * minionCount * 3 + 1)) { summonMinions(monst); return true; @@ -2430,9 +2240,7 @@ boolean generallyValidBoltTarget(creature *caster, creature *target) { // Can't target yourself; that's the fundamental theorem of Brogue bolts. return false; } - if (caster->status[STATUS_DISCORDANT] - && caster->creatureState == MONSTER_WANDERING - && target == &player) { + if (caster->status[STATUS_DISCORDANT] && caster->creatureState == MONSTER_WANDERING && target == &player) { // Discordant monsters always try to cast spells regardless of whether // they're hunting the player, so that they cast at other monsters. This // by bypasses the usual awareness checks, so the player and any allies @@ -2440,14 +2248,12 @@ boolean generallyValidBoltTarget(creature *caster, creature *target) { // bolts if we're discordant and wandering. return false; } - if (caster->creatureState == MONSTER_ALLY && !caster->status[STATUS_DISCORDANT] - && (target->bookkeepingFlags & MB_MARKED_FOR_SACRIFICE)) { + if (caster->creatureState == MONSTER_ALLY && !caster->status[STATUS_DISCORDANT] && (target->bookkeepingFlags & MB_MARKED_FOR_SACRIFICE)) { // Don't let (sane) allies cast at sacrifice targets. return false; } - if (monsterIsHidden(target, caster) - || (target->bookkeepingFlags & MB_SUBMERGED)) { + if (monsterIsHidden(target, caster) || (target->bookkeepingFlags & MB_SUBMERGED)) { // No bolt will affect a submerged creature. Can't shoot at invisible creatures unless it's in gas. return false; } @@ -2461,9 +2267,7 @@ boolean targetEligibleForCombatBuff(creature *caster, creature *target) { for (creatureIterator it = iterateCreatures(monsters); !handledPlayer || hasNextCreature(it);) { creature *enemy = !handledPlayer ? &player : nextCreature(&it); handledPlayer = true; - if (monstersAreEnemies(&player, enemy) - && canSeeMonster(enemy) - && (pmapAt(enemy->loc)->flags & IN_FIELD_OF_VIEW)) { + if (monstersAreEnemies(&player, enemy) && canSeeMonster(enemy) && (pmapAt(enemy->loc)->flags & IN_FIELD_OF_VIEW)) { return true; } @@ -2479,24 +2283,19 @@ boolean targetEligibleForCombatBuff(creature *caster, creature *target) { // Assumes that the conditions in generallyValidBoltTarget have already been satisfied. boolean specificallyValidBoltTarget(creature *caster, creature *target, enum boltType theBoltType) { - if ((boltCatalog[theBoltType].flags & BF_TARGET_ALLIES) - && (!monstersAreTeammates(caster, target) || monstersAreEnemies(caster, target))) { + if ((boltCatalog[theBoltType].flags & BF_TARGET_ALLIES) && (!monstersAreTeammates(caster, target) || monstersAreEnemies(caster, target))) { return false; } - if ((boltCatalog[theBoltType].flags & BF_TARGET_ENEMIES) - && (!monstersAreEnemies(caster, target))) { + if ((boltCatalog[theBoltType].flags & BF_TARGET_ENEMIES) && (!monstersAreEnemies(caster, target))) { return false; } - if ((boltCatalog[theBoltType].flags & BF_TARGET_ENEMIES) - && (target->info.flags & MONST_INVULNERABLE)) { + if ((boltCatalog[theBoltType].flags & BF_TARGET_ENEMIES) && (target->info.flags & MONST_INVULNERABLE)) { return false; } - if ((target->info.flags & MONST_REFLECT_4) - && target->creatureState != MONSTER_ALLY - && !(boltCatalog[theBoltType].flags & (BF_NEVER_REFLECTS | BF_HALTS_BEFORE_OBSTRUCTION))) { + if ((target->info.flags & MONST_REFLECT_4) && target->creatureState != MONSTER_ALLY && !(boltCatalog[theBoltType].flags & (BF_NEVER_REFLECTS | BF_HALTS_BEFORE_OBSTRUCTION))) { // Don't fire a reflectable bolt at a reflective target unless it's your ally. return false; } @@ -2504,13 +2303,11 @@ boolean specificallyValidBoltTarget(creature *caster, creature *target, enum bol // Don't fire a bolt at a creature type that it won't affect. return false; } - if ((boltCatalog[theBoltType].flags & BF_FIERY) - && target->status[STATUS_IMMUNE_TO_FIRE]) { + if ((boltCatalog[theBoltType].flags & BF_FIERY) && target->status[STATUS_IMMUNE_TO_FIRE]) { // Don't shoot fireballs at fire-immune creatures. return false; } - if ((boltCatalog[theBoltType].flags & BF_FIERY) - && burnedTerrainFlagsAtLoc(caster->loc.x, caster->loc.y) & avoidedFlagsForMonster(&(caster->info))) { + if ((boltCatalog[theBoltType].flags & BF_FIERY) && burnedTerrainFlagsAtLoc(caster->loc.x, caster->loc.y) & avoidedFlagsForMonster(&(caster->info))) { // Don't shoot fireballs if you're standing on a tile that could combust into something that harms you. return false; } @@ -2523,15 +2320,13 @@ boolean specificallyValidBoltTarget(creature *caster, creature *target, enum bol } break; case BE_ATTACK: - if (cellHasTerrainFlag(target->loc.x, target->loc.y, T_OBSTRUCTS_PASSABILITY) - && !(target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { + if (cellHasTerrainFlag(target->loc.x, target->loc.y, T_OBSTRUCTS_PASSABILITY) && !(target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { // Don't shoot an arrow at an embedded creature. return false; } // continue to BE_DAMAGE below case BE_DAMAGE: - if (target->status[STATUS_ENTRANCED] - && monstersAreEnemies(caster, target)) { + if (target->status[STATUS_ENTRANCED] && monstersAreEnemies(caster, target)) { // Don't break your enemies' entrancement. return false; } @@ -2541,22 +2336,18 @@ boolean specificallyValidBoltTarget(creature *caster, creature *target, enum bol // so our logic has to follow from the terrain parameters of the bolt's target DF. if (boltCatalog[theBoltType].targetDF) { const unsigned long terrainFlags = tileCatalog[dungeonFeatureCatalog[boltCatalog[theBoltType].targetDF].tile].flags; - if ((terrainFlags & T_ENTANGLES) - && target->status[STATUS_STUCK]) { + if ((terrainFlags & T_ENTANGLES) && target->status[STATUS_STUCK]) { // Don't try to entangle a creature that is already entangled. return false; } - if ((boltCatalog[theBoltType].flags & BF_TARGET_ENEMIES) - && !(terrainFlags & avoidedFlagsForMonster(&(target->info))) - && (!(terrainFlags & T_ENTANGLES) || (target->info.flags & MONST_IMMUNE_TO_WEBS))) { + if ((boltCatalog[theBoltType].flags & BF_TARGET_ENEMIES) && !(terrainFlags & avoidedFlagsForMonster(&(target->info))) && (!(terrainFlags & T_ENTANGLES) || (target->info.flags & MONST_IMMUNE_TO_WEBS))) { return false; } } break; case BE_DISCORD: - if (target->status[STATUS_DISCORDANT] - || target == &player) { + if (target->status[STATUS_DISCORDANT] || target == &player) { // Don't cast discord if the target is already discordant, or if it is the player. // (Players should never be intentionally targeted by discord. It's just a fact of monster psychology.) return false; @@ -2572,20 +2363,16 @@ boolean specificallyValidBoltTarget(creature *caster, creature *target, enum bol // Dispel magic creatures; strip weapon invulnerability from revenants. return true; } - if ((target->status[STATUS_IMMUNE_TO_FIRE] || target->status[STATUS_LEVITATING]) - && cellHasTerrainFlag(target->loc.x, target->loc.y, (T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_AUTO_DESCENT))) { + if ((target->status[STATUS_IMMUNE_TO_FIRE] || target->status[STATUS_LEVITATING]) && cellHasTerrainFlag(target->loc.x, target->loc.y, (T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_AUTO_DESCENT))) { // Drop the target into lava or a chasm if opportunity knocks. return true; } - if (monstersAreTeammates(caster, target) - && target->status[STATUS_DISCORDANT] - && !(target->info.flags & MONST_DIES_IF_NEGATED)) { + if (monstersAreTeammates(caster, target) && target->status[STATUS_DISCORDANT] && !(target->info.flags & MONST_DIES_IF_NEGATED)) { // Dispel discord from allies unless it would destroy them. return true; } } else if (monstersAreTeammates(caster, target)) { - if (target == &player && rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && (rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) - && rogue.armor->enchant2 == A_REFLECTION && netEnchant(rogue.armor) > 0) { + if (target == &player && rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && (rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) && rogue.armor->enchant2 == A_REFLECTION && netEnchant(rogue.armor) > 0) { // Allies shouldn't cast negation on the player if she's knowingly wearing armor of reflection. // Too much risk of negating themselves in the process. return false; @@ -2594,8 +2381,7 @@ boolean specificallyValidBoltTarget(creature *caster, creature *target, enum bol // Never cast negation if it would destroy an allied creature. return false; } - if (target->status[STATUS_ENTRANCED] - && caster->creatureState != MONSTER_ALLY) { + if (target->status[STATUS_ENTRANCED] && caster->creatureState != MONSTER_ALLY) { // Non-allied monsters will dispel entrancement on their own kind. return true; } @@ -2683,8 +2469,7 @@ boolean monstUseBolt(creature *monst) { continue; // Blinking is handled elsewhere. } if (specificallyValidBoltTarget(monst, target, monst->info.bolts[i])) { - if ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) - || rand_percent(30)) { + if ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30)) { monsterCastSpell(monst, target, monst->info.bolts[i]); return true; @@ -2712,13 +2497,10 @@ boolean isLocalScentMaximum(short x, short y) { const short baselineScent = scentMap[x][y]; - for (dir=0; dir< DIRECTION_COUNT; dir++) { + for (dir = 0; dir < DIRECTION_COUNT; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && (scentMap[newX][newY] > baselineScent) - && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) - && !diagonalBlocked(x, y, newX, newY, false)) { + if (coordinatesAreInMap(newX, newY) && (scentMap[newX][newY] > baselineScent) && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) && !diagonalBlocked(x, y, newX, newY, false)) { return false; } @@ -2739,16 +2521,12 @@ enum directions scentDirection(creature *monst) { for (;;) { - for (dir=0; dir< DIRECTION_COUNT; dir++) { + for (dir = 0; dir < DIRECTION_COUNT; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - otherMonst = monsterAtLoc((pos){ newX, newY }); - if (coordinatesAreInMap(newX, newY) - && (scentMap[newX][newY] > bestNearbyScent) - && (!(pmap[newX][newY].flags & HAS_MONSTER) || (otherMonst && canPass(monst, otherMonst))) - && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) - && !diagonalBlocked(x, y, newX, newY, false) - && !monsterAvoids(monst, (pos){newX, newY})) { + otherMonst = monsterAtLoc((pos){newX, newY}); + if (coordinatesAreInMap(newX, newY) && (scentMap[newX][newY] > bestNearbyScent) && (!(pmap[newX][newY].flags & HAS_MONSTER) || (otherMonst && canPass(monst, otherMonst))) + && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) && !diagonalBlocked(x, y, newX, newY, false) && !monsterAvoids(monst, (pos){newX, newY})) { bestNearbyScent = scentMap[newX][newY]; bestDirection = dir; @@ -2765,10 +2543,10 @@ enum directions scentDirection(creature *monst) { // There's a possibility he's stuck for some other reason, though, so we'll only // try once per his move -- hence the failsafe. canTryAgain = false; - for (dir=0; dir<4; dir++) { + for (dir = 0; dir < 4; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - for (dir2=0; dir2<4; dir2++) { + for (dir2 = 0; dir2 < 4; dir2++) { newestX = newX + nbDirs[dir2][0]; newestY = newY + nbDirs[dir2][1]; if (coordinatesAreInMap(newX, newY) && coordinatesAreInMap(newestX, newestY)) { @@ -2791,10 +2569,7 @@ boolean resurrectAlly(const short x, const short y) { // legendary allies over everyone else). creature *monToCheck, *monToRaise = NULL; while (monToCheck = nextCreature(&allyIterator)) { - if (monToRaise == NULL - || monToCheck->totalPowerCount > monToRaise->totalPowerCount - || (monToCheck->totalPowerCount == monToRaise->totalPowerCount - && monToCheck->info.monsterID > monToRaise->info.monsterID)) { + if (monToRaise == NULL || monToCheck->totalPowerCount > monToRaise->totalPowerCount || (monToCheck->totalPowerCount == monToRaise->totalPowerCount && monToCheck->info.monsterID > monToRaise->info.monsterID)) { monToRaise = monToCheck; } @@ -2805,15 +2580,12 @@ boolean resurrectAlly(const short x, const short y) { removeCreature(&purgatory, monToRaise); prependCreature(monsters, monToRaise); - getQualifyingPathLocNear(&monToRaise->loc.x, &monToRaise->loc.y, x, y, true, - (T_PATHING_BLOCKER | T_HARMFUL_TERRAIN), 0, - 0, (HAS_PLAYER | HAS_MONSTER), false); + getQualifyingPathLocNear(&monToRaise->loc.x, &monToRaise->loc.y, x, y, true, (T_PATHING_BLOCKER | T_HARMFUL_TERRAIN), 0, 0, (HAS_PLAYER | HAS_MONSTER), false); pmapAt(monToRaise->loc)->flags |= HAS_MONSTER; // Restore health etc. monToRaise->bookkeepingFlags &= ~(MB_IS_DYING | MB_ADMINISTRATIVE_DEATH | MB_HAS_DIED | MB_IS_FALLING); - if (!(monToRaise->info.flags & MONST_FIERY) - && monToRaise->status[STATUS_BURNING]) { + if (!(monToRaise->info.flags & MONST_FIERY) && monToRaise->status[STATUS_BURNING]) { monToRaise->status[STATUS_BURNING] = 0; } @@ -2846,28 +2618,24 @@ boolean monsterFleesFrom(creature *monst, creature *defender) { return false; } - if ((defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) - && !(defender->info.flags & MONST_IMMOBILE)) { + if ((defender->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) && !(defender->info.flags & MONST_IMMOBILE)) { // Don't charge if the monster is damage-immune and is NOT immobile; // i.e., keep distance from revenants and stone guardians but not mirror totems. return true; } - if (monst->creatureState == MONSTER_ALLY && !monst->status[STATUS_DISCORDANT] - && (defender->bookkeepingFlags & MB_MARKED_FOR_SACRIFICE)) { + if (monst->creatureState == MONSTER_ALLY && !monst->status[STATUS_DISCORDANT] && (defender->bookkeepingFlags & MB_MARKED_FOR_SACRIFICE)) { // Willing allies shouldn't charge sacrifice targets. return true; } - if ((monst->info.flags & MONST_MAINTAINS_DISTANCE) - || (defender->info.abilityFlags & MA_KAMIKAZE)) { + if ((monst->info.flags & MONST_MAINTAINS_DISTANCE) || (defender->info.abilityFlags & MA_KAMIKAZE)) { // Don't charge if you maintain distance or if it's a kamikaze monster. return true; } - if (monst->info.abilityFlags & MA_POISONS - && defender->status[STATUS_POISONED] * defender->poisonAmount > defender->currentHP) { + if (monst->info.abilityFlags & MA_POISONS && defender->status[STATUS_POISONED] * defender->poisonAmount > defender->currentHP) { return true; } @@ -2887,10 +2655,7 @@ boolean allyFlees(creature *ally, creature *closestEnemy) { return false; } - if (distanceBetween((pos){x, y}, closestEnemy->loc) < 10 - && (100 * ally->currentHP / ally->info.maxHP <= 33) - && ally->info.turnsBetweenRegen > 0 - && !ally->carriedMonster + if (distanceBetween((pos){x, y}, closestEnemy->loc) < 10 && (100 * ally->currentHP / ally->info.maxHP <= 33) && ally->info.turnsBetweenRegen > 0 && !ally->carriedMonster && ((ally->info.flags & MONST_FLEES_NEAR_DEATH) || (100 * ally->currentHP / ally->info.maxHP * 2 < 100 * player.currentHP / player.info.maxHP))) { // Flee if you're within 10 spaces, your HP is under 1/3, you're not a phoenix or lich or vampire in bat form, // and you either flee near death or your health fraction is less than half of the player's. @@ -2899,7 +2664,8 @@ boolean allyFlees(creature *ally, creature *closestEnemy) { // so do allies that keep their distance or while in the presence of damage-immune or kamikaze enemies if (monsterFleesFrom(ally, closestEnemy)) { - // Flee if you're within 3 spaces and you either flee near death or the closest enemy is a bloat, revenant or guardian. + // Flee if you're within 3 spaces and you either flee near death or the closest enemy is a bloat, revenant or + // guardian. return true; } @@ -2915,10 +2681,7 @@ void monsterMillAbout(creature *monst, short movementChance) { if (rand_percent(movementChance)) { dir = randValidDirectionFrom(monst, x, y, true); if (dir != -1) { - pos targetLoc = { - x + nbDirs[dir][0], - y + nbDirs[dir][1] - }; + pos targetLoc = {x + nbDirs[dir][0], y + nbDirs[dir][1]}; moveMonsterPassivelyTowards(monst, targetLoc, false); } } @@ -2941,8 +2704,7 @@ void moveAlly(creature *monst) { } // If we're standing in harmful terrain and there is a way to escape it, spend this turn escaping it. - if (cellHasTerrainFlag(x, y, (T_HARMFUL_TERRAIN & ~(T_IS_FIRE | T_CAUSES_DAMAGE | T_CAUSES_PARALYSIS | T_CAUSES_CONFUSION))) - || (cellHasTerrainFlag(x, y, T_IS_FIRE) && !monst->status[STATUS_IMMUNE_TO_FIRE]) + if (cellHasTerrainFlag(x, y, (T_HARMFUL_TERRAIN & ~(T_IS_FIRE | T_CAUSES_DAMAGE | T_CAUSES_PARALYSIS | T_CAUSES_CONFUSION))) || (cellHasTerrainFlag(x, y, T_IS_FIRE) && !monst->status[STATUS_IMMUNE_TO_FIRE]) || (cellHasTerrainFlag(x, y, T_CAUSES_DAMAGE | T_CAUSES_PARALYSIS | T_CAUSES_CONFUSION) && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)))) { if (!rogue.updatedMapToSafeTerrainThisTurn) { @@ -2956,10 +2718,7 @@ void moveAlly(creature *monst) { dir = nextStep(rogue.mapToSafeTerrain, x, y, monst, true); if (dir != -1) { - targetLoc = (pos){ - x + nbDirs[dir][0], - y + nbDirs[dir][1] - }; + targetLoc = (pos){x + nbDirs[dir][0], y + nbDirs[dir][1]}; if (moveMonsterPassivelyTowards(monst, targetLoc, false)) { return; } @@ -2970,12 +2729,8 @@ void moveAlly(creature *monst) { shortestDistance = max(DROWS, DCOLS); for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *target = nextCreature(&it); - if (target != monst - && (!(target->bookkeepingFlags & MB_SUBMERGED) || (monst->bookkeepingFlags & MB_SUBMERGED)) - && monsterWillAttackTarget(monst, target) - && distanceBetween((pos){x, y}, target->loc) < shortestDistance - && traversiblePathBetween(monst, target->loc.x, target->loc.y) - && (!cellHasTerrainFlag(target->loc.x, target->loc.y, T_OBSTRUCTS_PASSABILITY) || (target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) + if (target != monst && (!(target->bookkeepingFlags & MB_SUBMERGED) || (monst->bookkeepingFlags & MB_SUBMERGED)) && monsterWillAttackTarget(monst, target) && distanceBetween((pos){x, y}, target->loc) < shortestDistance + && traversiblePathBetween(monst, target->loc.x, target->loc.y) && (!cellHasTerrainFlag(target->loc.x, target->loc.y, T_OBSTRUCTS_PASSABILITY) || (target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) && (!target->status[STATUS_INVISIBLE] || rand_percent(33))) { shortestDistance = distanceBetween((pos){x, y}, target->loc); @@ -2985,9 +2740,7 @@ void moveAlly(creature *monst) { // Weak allies in the presence of enemies seek safety; if (allyFlees(monst, closestMonster)) { - if (monsterHasBoltEffect(monst, BE_BLINKING) - && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30)) - && monsterBlinkToSafety(monst)) { + if (monsterHasBoltEffect(monst, BE_BLINKING) && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30)) && monsterBlinkToSafety(monst)) { return; } @@ -2999,14 +2752,9 @@ void moveAlly(creature *monst) { } dir = nextStep(allySafetyMap, monst->loc.x, monst->loc.y, monst, true); if (dir != -1) { - targetLoc = (pos){ - x + nbDirs[dir][0], - y + nbDirs[dir][1] - }; - } - if (dir == -1 - || (allySafetyMap[targetLoc.x][targetLoc.y] >= allySafetyMap[x][y]) - || (!moveMonster(monst, nbDirs[dir][0], nbDirs[dir][1]) && !moveMonsterPassivelyTowards(monst, targetLoc, true))) { + targetLoc = (pos){x + nbDirs[dir][0], y + nbDirs[dir][1]}; + } + if (dir == -1 || (allySafetyMap[targetLoc.x][targetLoc.y] >= allySafetyMap[x][y]) || (!moveMonster(monst, nbDirs[dir][0], nbDirs[dir][1]) && !moveMonsterPassivelyTowards(monst, targetLoc, true))) { // ally can't flee; continue below } else { return; @@ -3027,30 +2775,25 @@ void moveAlly(creature *monst) { leashLength = 4; } if (shortestDistance == 1) { - if (closestMonster->movementSpeed < monst->movementSpeed - && !(closestMonster->info.flags & (MONST_FLITS | MONST_IMMOBILE)) - && closestMonster->creatureState == MONSTER_TRACKING_SCENT) { + if (closestMonster->movementSpeed < monst->movementSpeed && !(closestMonster->info.flags & (MONST_FLITS | MONST_IMMOBILE)) && closestMonster->creatureState == MONSTER_TRACKING_SCENT) { // Never try to flee from combat with a faster enemy. leashLength = max(DCOLS, DROWS); } else { - leashLength++; // If the ally is adjacent to a monster at the end of its leash, it shouldn't be prevented from attacking. + leashLength++; // If the ally is adjacent to a monster at the end of its leash, it shouldn't be prevented + // from attacking. } } - if (closestMonster - && (distanceBetween((pos){x, y}, player.loc) < leashLength || (monst->bookkeepingFlags & MB_DOES_NOT_TRACK_LEADER)) - && !(monst->info.flags & MONST_MAINTAINS_DISTANCE) - && !attackWouldBeFutile(monst, closestMonster)) { + if (closestMonster && (distanceBetween((pos){x, y}, player.loc) < leashLength || (monst->bookkeepingFlags & MB_DOES_NOT_TRACK_LEADER)) && !(monst->info.flags & MONST_MAINTAINS_DISTANCE) && !attackWouldBeFutile(monst, closestMonster)) { // Blink toward an enemy? - if (monsterHasBoltEffect(monst, BE_BLINKING) - && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30))) { + if (monsterHasBoltEffect(monst, BE_BLINKING) && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30))) { enemyMap = allocGrid(); costMap = allocGrid(); - for (i=0; ibookkeepingFlags & MB_SUBMERGED) || (monst->bookkeepingFlags & MB_SUBMERGED)) - && monsterWillAttackTarget(monst, target) - && distanceBetween((pos){x, y}, target->loc) < shortestDistance - && traversiblePathBetween(monst, target->loc.x, target->loc.y) - && (!monsterAvoids(monst, target->loc) || (target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) + if (target != monst && (!(target->bookkeepingFlags & MB_SUBMERGED) || (monst->bookkeepingFlags & MB_SUBMERGED)) && monsterWillAttackTarget(monst, target) && distanceBetween((pos){x, y}, target->loc) < shortestDistance + && traversiblePathBetween(monst, target->loc.x, target->loc.y) && (!monsterAvoids(monst, target->loc) || (target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) && (!target->status[STATUS_INVISIBLE] || ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(33)))) { enemyMap[target->loc.x][target->loc.y] = 0; @@ -3092,12 +2831,9 @@ void moveAlly(creature *monst) { targetLoc = closestMonster->loc; moveMonsterPassivelyTowards(monst, targetLoc, false); - } else if (isPosInMap(monst->targetCorpseLoc) - && !monst->status[STATUS_POISONED] - && (!monst->status[STATUS_BURNING] || monst->status[STATUS_IMMUNE_TO_FIRE])) { // Going to start eating a corpse. + } else if (isPosInMap(monst->targetCorpseLoc) && !monst->status[STATUS_POISONED] && (!monst->status[STATUS_BURNING] || monst->status[STATUS_IMMUNE_TO_FIRE])) { // Going to start eating a corpse. moveMonsterPassivelyTowards(monst, monst->targetCorpseLoc, false); - if (posEq(monst->loc, monst->targetCorpseLoc) - && !(monst->bookkeepingFlags & MB_ABSORBING)) { + if (posEq(monst->loc, monst->targetCorpseLoc) && !(monst->bookkeepingFlags & MB_ABSORBING)) { if (canSeeMonster(monst)) { monsterName(monstName, monst, true); sprintf(buf, "%s begins %s the fallen %s.", monstName, monsterText[monst->info.monsterID].absorbing, monst->targetCorpseName); @@ -3106,15 +2842,12 @@ void moveAlly(creature *monst) { monst->corpseAbsorptionCounter = 20; monst->bookkeepingFlags |= MB_ABSORBING; } - } else if ((monst->bookkeepingFlags & MB_DOES_NOT_TRACK_LEADER) - || (distanceBetween((pos){x, y}, player.loc) < 3 && (pmap[x][y].flags & IN_FIELD_OF_VIEW))) { + } else if ((monst->bookkeepingFlags & MB_DOES_NOT_TRACK_LEADER) || (distanceBetween((pos){x, y}, player.loc) < 3 && (pmap[x][y].flags & IN_FIELD_OF_VIEW))) { monst->bookkeepingFlags &= ~MB_GIVEN_UP_ON_SCENT; monsterMillAbout(monst, 30); } else { - if (!(monst->bookkeepingFlags & MB_GIVEN_UP_ON_SCENT) - && distanceBetween((pos){x, y}, player.loc) > 10 - && monsterBlinkToPreferenceMap(monst, scentMap, true)) { + if (!(monst->bookkeepingFlags & MB_GIVEN_UP_ON_SCENT) && distanceBetween((pos){x, y}, player.loc) > 10 && monsterBlinkToPreferenceMap(monst, scentMap, true)) { monst->ticksUntilTurn = monst->attackSpeed * (monst->info.flags & MONST_CAST_SPELLS_SLOWLY ? 2 : 1); return; @@ -3124,10 +2857,7 @@ void moveAlly(creature *monst) { monst->bookkeepingFlags |= MB_GIVEN_UP_ON_SCENT; pathTowardCreature(monst, monst->leader); } else { - targetLoc = (pos) { - x + nbDirs[dir][0], - y + nbDirs[dir][1] - }; + targetLoc = (pos){x + nbDirs[dir][0], y + nbDirs[dir][1]}; moveMonsterPassivelyTowards(monst, targetLoc, false); } } @@ -3138,13 +2868,13 @@ boolean updateMonsterCorpseAbsorption(creature *monst) { short i; char buf[COLS], buf2[COLS]; - if (posEq(monst->loc, monst->targetCorpseLoc) - && (monst->bookkeepingFlags & MB_ABSORBING)) { + if (posEq(monst->loc, monst->targetCorpseLoc) && (monst->bookkeepingFlags & MB_ABSORBING)) { if (--monst->corpseAbsorptionCounter <= 0) { monst->targetCorpseLoc = INVALID_POS; if (monst->absorptionBolt != BOLT_NONE) { - for (i=0; monst->info.bolts[i] != BOLT_NONE; i++); + for (i = 0; monst->info.bolts[i] != BOLT_NONE; i++) + ; monst->info.bolts[i] = monst->absorptionBolt; } else if (monst->absorbBehavior) { monst->info.flags |= monst->absorptionFlags; @@ -3216,9 +2946,7 @@ void monstersTurn(creature *monst) { return; } - if (monst->info.DFChance - && (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) - && rand_percent(monst->info.DFChance)) { + if (monst->info.DFChance && (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) && rand_percent(monst->info.DFChance)) { spawnDungeonFeature(monst->loc.x, monst->loc.y, &dungeonFeatureCatalog[monst->info.DFType], true, false); } @@ -3278,13 +3006,8 @@ void monstersTurn(creature *monst) { for (creatureIterator it = iterateCreatures(monsters); !handledPlayer || hasNextCreature(it);) { creature *target = !handledPlayer ? &player : nextCreature(&it); handledPlayer = true; - if (target != monst - && (!(target->bookkeepingFlags & MB_SUBMERGED) || (monst->bookkeepingFlags & MB_SUBMERGED)) - && monsterWillAttackTarget(monst, target) - && distanceBetween((pos){x, y}, target->loc) < shortestDistance - && traversiblePathBetween(monst, target->loc.x, target->loc.y) - && (!monsterAvoids(monst, target->loc) || (target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) - && (!target->status[STATUS_INVISIBLE] || rand_percent(33))) { + if (target != monst && (!(target->bookkeepingFlags & MB_SUBMERGED) || (monst->bookkeepingFlags & MB_SUBMERGED)) && monsterWillAttackTarget(monst, target) && distanceBetween((pos){x, y}, target->loc) < shortestDistance + && traversiblePathBetween(monst, target->loc.x, target->loc.y) && (!monsterAvoids(monst, target->loc) || (target->info.flags & MONST_ATTACKABLE_THRU_WALLS)) && (!target->status[STATUS_INVISIBLE] || rand_percent(33))) { shortestDistance = distanceBetween((pos){x, y}, target->loc); closestMonster = target; @@ -3303,29 +3026,22 @@ void monstersTurn(creature *monst) { } // hunting - if ((monst->creatureState == MONSTER_TRACKING_SCENT - || (monst->creatureState == MONSTER_ALLY && monst->status[STATUS_DISCORDANT])) + if ((monst->creatureState == MONSTER_TRACKING_SCENT || (monst->creatureState == MONSTER_ALLY && monst->status[STATUS_DISCORDANT])) // eels don't charge if you're not in the water && (!(monst->info.flags & MONST_RESTRICTED_TO_LIQUID) || cellHasTMFlag(player.loc.x, player.loc.y, TM_ALLOWS_SUBMERGING))) { // magic users sometimes cast spells - if (monstUseMagic(monst) - || (monsterHasBoltEffect(monst, BE_BLINKING) - && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30)) - && monsterBlinkToPreferenceMap(monst, scentMap, true))) { // if he actually cast a spell + if (monstUseMagic(monst) || (monsterHasBoltEffect(monst, BE_BLINKING) && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30)) && monsterBlinkToPreferenceMap(monst, scentMap, true))) { // if he actually cast a spell - monst->ticksUntilTurn = monst->attackSpeed * (monst->info.flags & MONST_CAST_SPELLS_SLOWLY ? 2 : 1); - return; - } + monst->ticksUntilTurn = monst->attackSpeed * (monst->info.flags & MONST_CAST_SPELLS_SLOWLY ? 2 : 1); + return; + } // if the monster is adjacent to an ally and not adjacent to the player, attack the ally - if (distanceBetween((pos){x, y}, player.loc) > 1 - || diagonalBlocked(x, y, player.loc.x, player.loc.y, false)) { + if (distanceBetween((pos){x, y}, player.loc) > 1 || diagonalBlocked(x, y, player.loc.x, player.loc.y, false)) { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *ally = nextCreature(&it); - if (monsterWillAttackTarget(monst, ally) - && distanceBetween((pos){x, y}, ally->loc) == 1 - && (!ally->status[STATUS_INVISIBLE] || rand_percent(33))) { + if (monsterWillAttackTarget(monst, ally) && distanceBetween((pos){x, y}, ally->loc) == 1 && (!ally->status[STATUS_INVISIBLE] || rand_percent(33))) { targetLoc = ally->loc; if (moveMonsterPassivelyTowards(monst, targetLoc, true)) { // attack @@ -3341,8 +3057,7 @@ void monstersTurn(creature *monst) { moveMonsterPassivelyTowards(monst, player.loc, true); // attack return; } - if ((monst->info.flags & MONST_ALWAYS_HUNTING) - && (monst->bookkeepingFlags & MB_GIVEN_UP_ON_SCENT)) { + if ((monst->info.flags & MONST_ALWAYS_HUNTING) && (monst->bookkeepingFlags & MB_GIVEN_UP_ON_SCENT)) { pathTowardCreature(monst, &player); return; @@ -3367,9 +3082,7 @@ void monstersTurn(creature *monst) { } } else if (monst->creatureState == MONSTER_FLEEING) { // fleeing - if (monsterHasBoltEffect(monst, BE_BLINKING) - && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30)) - && monsterBlinkToSafety(monst)) { + if (monsterHasBoltEffect(monst, BE_BLINKING) && ((monst->info.flags & MONST_ALWAYS_USE_ABILITY) || rand_percent(30)) && monsterBlinkToSafety(monst)) { return; } @@ -3380,10 +3093,7 @@ void monstersTurn(creature *monst) { dir = nextStep(getSafetyMap(monst), monst->loc.x, monst->loc.y, NULL, true); if (dir != -1) { - targetLoc = (pos){ - x + nbDirs[dir][0], - y + nbDirs[dir][1] - }; + targetLoc = (pos){x + nbDirs[dir][0], y + nbDirs[dir][1]}; } if (dir == -1 || (!moveMonster(monst, nbDirs[dir][0], nbDirs[dir][1]) && !moveMonsterPassivelyTowards(monst, targetLoc, true))) { boolean handledPlayer = false; @@ -3391,8 +3101,7 @@ void monstersTurn(creature *monst) { creature *ally = !handledPlayer ? &player : nextCreature(&it); handledPlayer = true; if (!monst->status[STATUS_MAGICAL_FEAR] // Fearful monsters will never attack. - && monsterWillAttackTarget(monst, ally) - && distanceBetween((pos){x, y}, ally->loc) <= 1) { + && monsterWillAttackTarget(monst, ally) && distanceBetween((pos){x, y}, ally->loc) <= 1) { moveMonster(monst, ally->loc.x - x, ally->loc.y - y); // attack the player if cornered return; @@ -3405,8 +3114,7 @@ void monstersTurn(creature *monst) { || ((monst->info.flags & MONST_RESTRICTED_TO_LIQUID) && !cellHasTMFlag(player.loc.x, player.loc.y, TM_ALLOWS_SUBMERGING))) { // if we're standing in harmful terrain and there is a way to escape it, spend this turn escaping it. - if (cellHasTerrainFlag(x, y, (T_HARMFUL_TERRAIN & ~T_IS_FIRE)) - || (cellHasTerrainFlag(x, y, T_IS_FIRE) && !monst->status[STATUS_IMMUNE_TO_FIRE] && !(monst->info.flags & MONST_INVULNERABLE))) { + if (cellHasTerrainFlag(x, y, (T_HARMFUL_TERRAIN & ~T_IS_FIRE)) || (cellHasTerrainFlag(x, y, T_IS_FIRE) && !monst->status[STATUS_IMMUNE_TO_FIRE] && !(monst->info.flags & MONST_INVULNERABLE))) { if (!rogue.updatedMapToSafeTerrainThisTurn) { updateSafeTerrainMap(); } @@ -3418,10 +3126,7 @@ void monstersTurn(creature *monst) { dir = nextStep(rogue.mapToSafeTerrain, x, y, monst, true); if (dir != -1) { - targetLoc = (pos) { - x + nbDirs[dir][0], - y + nbDirs[dir][1] - }; + targetLoc = (pos){x + nbDirs[dir][0], y + nbDirs[dir][1]}; if (moveMonsterPassivelyTowards(monst, targetLoc, true)) { return; } @@ -3430,12 +3135,8 @@ void monstersTurn(creature *monst) { // if a captive leader is captive, regenerative and healthy enough to withstand an attack, // and we're not poisonous, then approach or attack him. - if ((monst->bookkeepingFlags & MB_FOLLOWER) - && (monst->leader->bookkeepingFlags & MB_CAPTIVE) - && monst->leader->currentHP > (int) (monst->info.damage.upperBound * monsterDamageAdjustmentAmount(monst) / FP_FACTOR) - && monst->leader->info.turnsBetweenRegen > 0 - && !(monst->info.abilityFlags & MA_POISONS) - && !diagonalBlocked(monst->loc.x, monst->loc.y, monst->leader->loc.x, monst->leader->loc.y, false)) { + if ((monst->bookkeepingFlags & MB_FOLLOWER) && (monst->leader->bookkeepingFlags & MB_CAPTIVE) && monst->leader->currentHP > (int)(monst->info.damage.upperBound * monsterDamageAdjustmentAmount(monst) / FP_FACTOR) + && monst->leader->info.turnsBetweenRegen > 0 && !(monst->info.abilityFlags & MA_POISONS) && !diagonalBlocked(monst->loc.x, monst->loc.y, monst->leader->loc.x, monst->leader->loc.y, false)) { if (distanceBetween(monst->loc, monst->leader->loc) == 1) { // Attack if adjacent. @@ -3453,9 +3154,7 @@ void monstersTurn(creature *monst) { if (monst->creatureState == MONSTER_WANDERING) { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *ally = nextCreature(&it); - if (monsterWillAttackTarget(monst, ally) - && distanceBetween((pos){x, y}, ally->loc) == 1 - && (!ally->status[STATUS_INVISIBLE] || rand_percent(33))) { + if (monsterWillAttackTarget(monst, ally) && distanceBetween((pos){x, y}, ally->loc) == 1 && (!ally->status[STATUS_INVISIBLE] || rand_percent(33))) { targetLoc = ally->loc; if (moveMonsterPassivelyTowards(monst, targetLoc, true)) { @@ -3483,8 +3182,7 @@ void monstersTurn(creature *monst) { dir = nextStep(rogue.wpDistance[monst->targetWaypointIndex], monst->loc.x, monst->loc.y, monst, false); } // If there's no path forward, call that waypoint finished and pick a new one. - if (!isValidWanderDestination(monst, monst->targetWaypointIndex) - || dir == NO_DIRECTION) { + if (!isValidWanderDestination(monst, monst->targetWaypointIndex) || dir == NO_DIRECTION) { chooseNewWanderDestination(monst); if (isValidWanderDestination(monst, monst->targetWaypointIndex)) { @@ -3497,10 +3195,7 @@ void monstersTurn(creature *monst) { dir = randValidDirectionFrom(monst, x, y, true); } if (dir != NO_DIRECTION) { - targetLoc = (pos) { - x + nbDirs[dir][0], - y + nbDirs[dir][1] - }; + targetLoc = (pos){x + nbDirs[dir][0], y + nbDirs[dir][1]}; if (moveMonsterPassivelyTowards(monst, targetLoc, true)) { return; } @@ -3517,17 +3212,12 @@ boolean canPass(creature *mover, creature *blocker) { return false; } - if (blocker->status[STATUS_CONFUSED] - || blocker->status[STATUS_STUCK] - || blocker->status[STATUS_PARALYZED] - || blocker->status[STATUS_ENTRANCED] - || mover->status[STATUS_ENTRANCED]) { + if (blocker->status[STATUS_CONFUSED] || blocker->status[STATUS_STUCK] || blocker->status[STATUS_PARALYZED] || blocker->status[STATUS_ENTRANCED] || mover->status[STATUS_ENTRANCED]) { return false; } - if ((blocker->bookkeepingFlags & (MB_CAPTIVE | MB_ABSORBING)) - || (blocker->info.flags & MONST_IMMOBILE)) { + if ((blocker->bookkeepingFlags & (MB_CAPTIVE | MB_ABSORBING)) || (blocker->info.flags & MONST_IMMOBILE)) { return false; } @@ -3543,20 +3233,15 @@ boolean canPass(creature *mover, creature *blocker) { return false; } - return (monstersAreTeammates(mover, blocker) - && blocker->currentHP < mover->currentHP); + return (monstersAreTeammates(mover, blocker) && blocker->currentHP < mover->currentHP); } -boolean isPassableOrSecretDoor(short x, short y) { - return (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) - || (cellHasTMFlag(x, y, TM_IS_SECRET) && !(discoveredTerrainFlagsAtLoc(x, y) & T_OBSTRUCTS_PASSABILITY))); -} +boolean isPassableOrSecretDoor(short x, short y) { return (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) || (cellHasTMFlag(x, y, TM_IS_SECRET) && !(discoveredTerrainFlagsAtLoc(x, y) & T_OBSTRUCTS_PASSABILITY))); } boolean knownToPlayerAsPassableOrSecretDoor(short x, short y) { unsigned long tFlags, TMFlags; getLocationFlags(x, y, &tFlags, &TMFlags, NULL, true); - return (!(tFlags & T_OBSTRUCTS_PASSABILITY) - || ((TMFlags & TM_IS_SECRET) && !(discoveredTerrainFlagsAtLoc(x, y) & T_OBSTRUCTS_PASSABILITY))); + return (!(tFlags & T_OBSTRUCTS_PASSABILITY) || ((TMFlags & TM_IS_SECRET) && !(discoveredTerrainFlagsAtLoc(x, y) & T_OBSTRUCTS_PASSABILITY))); } void setMonsterLocation(creature *monst, short newX, short newY) { @@ -3570,9 +3255,7 @@ void setMonsterLocation(creature *monst, short newX, short newY) { if ((monst->bookkeepingFlags & MB_SUBMERGED) && !cellHasTMFlag(newX, newY, TM_ALLOWS_SUBMERGING)) { monst->bookkeepingFlags &= ~MB_SUBMERGED; } - if (playerCanSee(newX, newY) - && cellHasTMFlag(newX, newY, TM_IS_SECRET) - && cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY)) { + if (playerCanSee(newX, newY) && cellHasTMFlag(newX, newY, TM_IS_SECRET) && cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY)) { discover(newX, newY); // if you see a monster use a secret door, you discover it } @@ -3607,7 +3290,7 @@ boolean moveMonster(creature *monst, short dx, short dy) { newY = y + dy; if (!coordinatesAreInMap(newX, newY)) { - //DEBUG printf("\nProblem! Monster trying to move more than one space at a time."); + // DEBUG printf("\nProblem! Monster trying to move more than one space at a time."); return false; } @@ -3644,10 +3327,8 @@ boolean moveMonster(creature *monst, short dx, short dy) { } // Caught in spiderweb? - if (monst->status[STATUS_STUCK] && !(pmap[newX][newY].flags & (HAS_PLAYER | HAS_MONSTER)) - && cellHasTerrainFlag(x, y, T_ENTANGLES) && !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) { - if (!(monst->info.flags & MONST_INVULNERABLE) - && --monst->status[STATUS_STUCK]) { + if (monst->status[STATUS_STUCK] && !(pmap[newX][newY].flags & (HAS_PLAYER | HAS_MONSTER)) && cellHasTerrainFlag(x, y, T_ENTANGLES) && !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) { + if (!(monst->info.flags & MONST_INVULNERABLE) && --monst->status[STATUS_STUCK]) { monst->ticksUntilTurn = monst->movementSpeed; return true; @@ -3657,14 +3338,12 @@ boolean moveMonster(creature *monst, short dx, short dy) { } if (pmap[newX][newY].flags & (HAS_MONSTER | HAS_PLAYER)) { - defender = monsterAtLoc((pos){ newX, newY }); + defender = monsterAtLoc((pos){newX, newY}); } else { if (monst->bookkeepingFlags & MB_SEIZED) { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *defender = nextCreature(&it); - if ((defender->bookkeepingFlags & MB_SEIZING) - && monstersAreEnemies(monst, defender) - && distanceBetween(monst->loc, defender->loc) == 1 + if ((defender->bookkeepingFlags & MB_SEIZING) && monstersAreEnemies(monst, defender) && distanceBetween(monst->loc, defender->loc) == 1 && !diagonalBlocked(monst->loc.x, monst->loc.y, defender->loc.x, defender->loc.y, false)) { monst->ticksUntilTurn = monst->movementSpeed; @@ -3678,104 +3357,93 @@ boolean moveMonster(creature *monst, short dx, short dy) { } } - for (dir = 0; dir < DIRECTION_COUNT; dir++) { - if (dx == nbDirs[dir][0] - && dy == nbDirs[dir][1]) { + if (dx == nbDirs[dir][0] && dy == nbDirs[dir][1]) { break; } } brogueAssert(dir != NO_DIRECTION); - if (handleWhipAttacks(monst, dir, NULL) - || handleSpearAttacks(monst, dir, NULL)) { + if (handleWhipAttacks(monst, dir, NULL) || handleSpearAttacks(monst, dir, NULL)) { monst->ticksUntilTurn = monst->attackSpeed; return true; } - if (((defender && (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) - || (isPassableOrSecretDoor(newX, newY) - && !diagonalBlocked(x, y, newX, newY, false) - && isPassableOrSecretDoor(x, y))) + if (((defender && (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) || (isPassableOrSecretDoor(newX, newY) && !diagonalBlocked(x, y, newX, newY, false) && isPassableOrSecretDoor(x, y))) && (!defender || canPass(monst, defender) || monsterWillAttackTarget(monst, defender))) { - // if it's a legal move + // if it's a legal move - if (defender) { - if (canPass(monst, defender)) { + if (defender) { + if (canPass(monst, defender)) { - // swap places - pmapAt(defender->loc)->flags &= ~HAS_MONSTER; - refreshDungeonCell(defender->loc.x, defender->loc.y); + // swap places + pmapAt(defender->loc)->flags &= ~HAS_MONSTER; + refreshDungeonCell(defender->loc.x, defender->loc.y); - pmapAt(monst->loc)->flags &= ~HAS_MONSTER; - refreshDungeonCell(monst->loc.x, monst->loc.y); + pmapAt(monst->loc)->flags &= ~HAS_MONSTER; + refreshDungeonCell(monst->loc.x, monst->loc.y); - monst->loc.x = newX; - monst->loc.y = newY; - pmapAt(monst->loc)->flags |= HAS_MONSTER; + monst->loc.x = newX; + monst->loc.y = newY; + pmapAt(monst->loc)->flags |= HAS_MONSTER; - if (monsterAvoids(defender, (pos){x, y})) { // don't want a flying monster to swap a non-flying monster into lava! - getQualifyingPathLocNear(&(defender->loc.x), &(defender->loc.y), x, y, true, - forbiddenFlagsForMonster(&(defender->info)), HAS_PLAYER, - forbiddenFlagsForMonster(&(defender->info)), (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); - } else { - defender->loc.x = x; - defender->loc.y = y; - } - pmapAt(defender->loc)->flags |= HAS_MONSTER; + if (monsterAvoids(defender, (pos){x, y})) { // don't want a flying monster to swap a non-flying monster into lava! + getQualifyingPathLocNear(&(defender->loc.x), &(defender->loc.y), x, y, true, forbiddenFlagsForMonster(&(defender->info)), HAS_PLAYER, forbiddenFlagsForMonster(&(defender->info)), (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), + false); + } else { + defender->loc.x = x; + defender->loc.y = y; + } + pmapAt(defender->loc)->flags |= HAS_MONSTER; - refreshDungeonCell(monst->loc.x, monst->loc.y); - refreshDungeonCell(defender->loc.x, defender->loc.y); + refreshDungeonCell(monst->loc.x, monst->loc.y); + refreshDungeonCell(defender->loc.x, defender->loc.y); - monst->ticksUntilTurn = monst->movementSpeed; - return true; + monst->ticksUntilTurn = monst->movementSpeed; + return true; + } + + // Sights are set on an enemy monster. Would we rather swarm than attack? + swarmDirection = monsterSwarmDirection(monst, defender); + if (swarmDirection != NO_DIRECTION) { + const pos newLoc = posNeighborInDirection(monst->loc, swarmDirection); + setMonsterLocation(monst, newLoc.x, newLoc.y); + monst->ticksUntilTurn = monst->movementSpeed; + return true; + } else { + // attacking another monster! + monst->ticksUntilTurn = monst->attackSpeed; + if (!((monst->info.abilityFlags & MA_SEIZES) && !(monst->bookkeepingFlags & MB_SEIZING))) { + // Bog monsters and krakens won't surface on the turn that they seize their target. + monst->bookkeepingFlags &= ~MB_SUBMERGED; } + refreshDungeonCell(x, y); - // Sights are set on an enemy monster. Would we rather swarm than attack? - swarmDirection = monsterSwarmDirection(monst, defender); - if (swarmDirection != NO_DIRECTION) { - const pos newLoc = posNeighborInDirection(monst->loc, swarmDirection); - setMonsterLocation(monst, newLoc.x, newLoc.y); - monst->ticksUntilTurn = monst->movementSpeed; - return true; - } else { - // attacking another monster! - monst->ticksUntilTurn = monst->attackSpeed; - if (!((monst->info.abilityFlags & MA_SEIZES) && !(monst->bookkeepingFlags & MB_SEIZING))) { - // Bog monsters and krakens won't surface on the turn that they seize their target. - monst->bookkeepingFlags &= ~MB_SUBMERGED; - } - refreshDungeonCell(x, y); - - buildHitList(hitList, monst, defender, - (monst->info.abilityFlags & MA_ATTACKS_ALL_ADJACENT) ? true : false); - // Attack! - for (i=0; i<16; i++) { - if (hitList[i] - && monsterWillAttackTarget(monst, hitList[i]) - && !(hitList[i]->bookkeepingFlags & MB_IS_DYING) - && !rogue.gameHasEnded) { - - attack(monst, hitList[i], false); - } + buildHitList(hitList, monst, defender, (monst->info.abilityFlags & MA_ATTACKS_ALL_ADJACENT) ? true : false); + // Attack! + for (i = 0; i < 16; i++) { + if (hitList[i] && monsterWillAttackTarget(monst, hitList[i]) && !(hitList[i]->bookkeepingFlags & MB_IS_DYING) && !rogue.gameHasEnded) { + + attack(monst, hitList[i], false); } } - return true; - } else { - // okay we're moving! - setMonsterLocation(monst, newX, newY); - monst->ticksUntilTurn = monst->movementSpeed; - return true; } + return true; + } else { + // okay we're moving! + setMonsterLocation(monst, newX, newY); + monst->ticksUntilTurn = monst->movementSpeed; + return true; } + } return false; } void clearStatus(creature *monst) { short i; - for (i=0; istatus[i] = monst->maxStatus[i] = 0; } } @@ -3792,13 +3460,10 @@ void findAlternativeHomeFor(creature *monst, short *x, short *y, boolean chooseR } for (maxPermissibleDifference = 1; maxPermissibleDifference < max(DCOLS, DROWS); maxPermissibleDifference++) { - for (i=0; i < DCOLS; i++) { - for (j=0; jloc.x) + abs(sRows[j] - monst->loc.y); - if (dist <= maxPermissibleDifference - && dist > 0 - && !(pmap[sCols[i]][sRows[j]].flags & (HAS_PLAYER | HAS_MONSTER)) - && !monsterAvoids(monst, (pos){sCols[i], sRows[j]}) + if (dist <= maxPermissibleDifference && dist > 0 && !(pmap[sCols[i]][sRows[j]].flags & (HAS_PLAYER | HAS_MONSTER)) && !monsterAvoids(monst, (pos){sCols[i], sRows[j]}) && !(monst == &player && cellHasTerrainFlag(sCols[i], sRows[j], T_PATHING_BLOCKER))) { // Success! @@ -3814,27 +3479,15 @@ void findAlternativeHomeFor(creature *monst, short *x, short *y, boolean chooseR } // blockingMap is optional -boolean getQualifyingLocNear(pos *loc, - short x, short y, - boolean hallwaysAllowed, - char blockingMap[DCOLS][DROWS], - unsigned long forbiddenTerrainFlags, - unsigned long forbiddenMapFlags, - boolean forbidLiquid, - boolean deterministic) { +boolean getQualifyingLocNear(pos *loc, short x, short y, boolean hallwaysAllowed, char blockingMap[DCOLS][DROWS], unsigned long forbiddenTerrainFlags, unsigned long forbiddenMapFlags, boolean forbidLiquid, boolean deterministic) { short candidateLocs = 0; // count up the number of candidate locations - for (int k=0; kloc.x, monst->loc.y, true, - (T_DIVIDES_LEVEL), 0, - T_OBSTRUCTS_ITEMS, (HAS_PLAYER | HAS_STAIRS | HAS_ITEM), false); + getQualifyingPathLocNear(&x, &y, monst->loc.x, monst->loc.y, true, (T_DIVIDES_LEVEL), 0, T_OBSTRUCTS_ITEMS, (HAS_PLAYER | HAS_STAIRS | HAS_ITEM), false); placeItem(monst->carriedItem, x, y); monst->carriedItem = NULL; refreshDungeonCell(x, y); @@ -3967,7 +3606,7 @@ void demoteMonsterFromLeadership(creature *monst) { for (int level = 0; level <= gameConst->deepestLevel; level++) { // we'll work on this level's monsters first, so that the new leader is preferably on the same level - creatureList *nearbyList = (level == 0 ? monsters : &levels[level-1].monsters); + creatureList *nearbyList = (level == 0 ? monsters : &levels[level - 1].monsters); for (creatureIterator it = iterateCreatures(nearbyList); hasNextCreature(it);) { creature *follower = nextCreature(&it); if (follower == monst || follower->leader != monst) continue; @@ -3991,13 +3630,12 @@ void demoteMonsterFromLeadership(creature *monst) { } } - if (newLeader - && !atLeastOneNewFollower) { + if (newLeader && !atLeastOneNewFollower) { newLeader->bookkeepingFlags &= ~MB_LEADER; } for (int level = 0; level <= gameConst->deepestLevel; level++) { - creatureList *candidateList = (level == 0 ? dormantMonsters : &levels[level-1].dormantMonsters); + creatureList *candidateList = (level == 0 ? dormantMonsters : &levels[level - 1].dormantMonsters); for (creatureIterator it = iterateCreatures(candidateList); hasNextCreature(it);) { creature *follower = nextCreature(&it); if (follower == monst || follower->leader != monst) continue; @@ -4021,21 +3659,10 @@ void toggleMonsterDormancy(creature *monst) { // Does it need a new location? if (pmapAt(monst->loc)->flags & (HAS_MONSTER | HAS_PLAYER)) { // Occupied! - getQualifyingPathLocNear( - &(monst->loc.x), - &(monst->loc.y), - monst->loc.x, - monst->loc.y, - true, - T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)), - HAS_PLAYER, - avoidedFlagsForMonster(&(monst->info)), - (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), - false - ); - // getQualifyingLocNear(loc, monst->loc.x, monst->loc.y, true, 0, T_PATHING_BLOCKER, (HAS_PLAYER | HAS_MONSTER), false, false); - // monst->loc.x = loc[0]; - // monst->loc.y = loc[1]; + getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), monst->loc.x, monst->loc.y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)), HAS_PLAYER, avoidedFlagsForMonster(&(monst->info)), + (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); + // getQualifyingLocNear(loc, monst->loc.x, monst->loc.y, true, 0, T_PATHING_BLOCKER, (HAS_PLAYER | + // HAS_MONSTER), false, false); monst->loc.x = loc[0]; monst->loc.y = loc[1]; } if (monst->bookkeepingFlags & MB_MARKED_FOR_SACRIFICE) { @@ -4072,35 +3699,22 @@ boolean staffOrWandEffectOnMonsterDescription(char *newText, item *theItem, crea boolean successfulDescription = false; fixpt enchant = netEnchant(theItem); - if ((theItem->category & (STAFF | WAND)) - && tableForItemCategory(theItem->category)[theItem->kind].identified) { + if ((theItem->category & (STAFF | WAND)) && tableForItemCategory(theItem->category)[theItem->kind].identified) { monsterName(monstName, monst, true); itemName(theItem, theItemName, false, false, NULL); switch (boltEffectForItem(theItem)) { case BE_DAMAGE: - if ((boltCatalog[boltForItem(theItem)].flags & BF_FIERY) && (monst->status[STATUS_IMMUNE_TO_FIRE]) - || (monst->info.flags & MONST_INVULNERABLE)) { + if ((boltCatalog[boltForItem(theItem)].flags & BF_FIERY) && (monst->status[STATUS_IMMUNE_TO_FIRE]) || (monst->info.flags & MONST_INVULNERABLE)) { - sprintf(newText, "\n Your %s (%c) will not harm %s.", - theItemName, - theItem->inventoryLetter, - monstName); + sprintf(newText, "\n Your %s (%c) will not harm %s.", theItemName, theItem->inventoryLetter, monstName); successfulDescription = true; } else if (theItem->flags & (ITEM_MAX_CHARGES_KNOWN | ITEM_IDENTIFIED)) { if (staffDamageLow(enchant) >= monst->currentHP) { - sprintf(newText, "\n Your %s (%c) will %s %s in one hit.", - theItemName, - theItem->inventoryLetter, - (monst->info.flags & MONST_INANIMATE) ? "destroy" : "kill", - monstName); + sprintf(newText, "\n Your %s (%c) will %s %s in one hit.", theItemName, theItem->inventoryLetter, (monst->info.flags & MONST_INANIMATE) ? "destroy" : "kill", monstName); } else { - sprintf(newText, "\n Your %s (%c) will hit %s for between %i%% and %i%% of $HISHER current health.", - theItemName, - theItem->inventoryLetter, - monstName, - 100 * staffDamageLow(enchant) / monst->currentHP, + sprintf(newText, "\n Your %s (%c) will hit %s for between %i%% and %i%% of $HISHER current health.", theItemName, theItem->inventoryLetter, monstName, 100 * staffDamageLow(enchant) / monst->currentHP, 100 * staffDamageHigh(enchant) / monst->currentHP); } successfulDescription = true; @@ -4108,37 +3722,24 @@ boolean staffOrWandEffectOnMonsterDescription(char *newText, item *theItem, crea break; case BE_POISON: if (monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) { - sprintf(newText, "\n Your %s (%c) will not affect %s.", - theItemName, - theItem->inventoryLetter, - monstName); + sprintf(newText, "\n Your %s (%c) will not affect %s.", theItemName, theItem->inventoryLetter, monstName); } else { - sprintf(newText, "\n Your %s (%c) will poison %s for %i%% of $HISHER current health.", - theItemName, - theItem->inventoryLetter, - monstName, - 100 * staffPoison(enchant) / monst->currentHP); + sprintf(newText, "\n Your %s (%c) will poison %s for %i%% of $HISHER current health.", theItemName, theItem->inventoryLetter, monstName, 100 * staffPoison(enchant) / monst->currentHP); } successfulDescription = true; break; case BE_DOMINATION: if (monst->creatureState != MONSTER_ALLY) { if (monst->info.flags & MONST_INANIMATE) { - sprintf(newText, "\n A wand of domination will have no effect on objects like %s.", - monstName); + sprintf(newText, "\n A wand of domination will have no effect on objects like %s.", monstName); } else if (monst->info.flags & MONST_INVULNERABLE) { - sprintf(newText, "\n A wand of domination will not affect %s.", - monstName); + sprintf(newText, "\n A wand of domination will not affect %s.", monstName); } else if (wandDominate(monst) <= 0) { - sprintf(newText, "\n A wand of domination will fail at %s's current health level.", - monstName); + sprintf(newText, "\n A wand of domination will fail at %s's current health level.", monstName); } else if (wandDominate(monst) >= 100) { - sprintf(newText, "\n A wand of domination will always succeed at %s's current health level.", - monstName); + sprintf(newText, "\n A wand of domination will always succeed at %s's current health level.", monstName); } else { - sprintf(newText, "\n A wand of domination will have a %i%% chance of success at %s's current health level.", - wandDominate(monst), - monstName); + sprintf(newText, "\n A wand of domination will have a %i%% chance of success at %s's current health level.", wandDominate(monst), monstName); } successfulDescription = true; } @@ -4152,7 +3753,7 @@ boolean staffOrWandEffectOnMonsterDescription(char *newText, item *theItem, crea } void monsterDetails(char buf[], creature *monst) { - char monstName[COLS], capMonstName[COLS], theItemName[COLS * 3], newText[20*COLS]; + char monstName[COLS], capMonstName[COLS], theItemName[COLS * 3], newText[20 * COLS]; short i, j, combatMath, combatMath2, playerKnownAverageDamage, playerKnownMaxDamage, commaCount, realArmorValue; boolean anyFlags, alreadyDisplayedDominationText = false; item *theItem; @@ -4164,8 +3765,7 @@ void monsterDetails(char buf[], creature *monst) { strcpy(capMonstName, monstName); upperCase(capMonstName); - if (!(monst->info.flags & MONST_RESTRICTED_TO_LIQUID) - || cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING)) { + if (!(monst->info.flags & MONST_RESTRICTED_TO_LIQUID) || cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING)) { // If the monster is not a beached whale, print the ordinary flavor text. sprintf(newText, " %s\n ", monsterText[monst->info.monsterID].flavorText); strcat(buf, newText); @@ -4183,12 +3783,9 @@ void monsterDetails(char buf[], creature *monst) { i = encodeMessageColor(buf, i, &white); } - if (!(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) - && cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY)) { + if (!(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) && cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY)) { // If the monster is trapped in impassible terrain, explain as much. - sprintf(newText, "%s is trapped %s %s.\n ", - capMonstName, - (tileCatalog[pmapAt(monst->loc)->layers[layerWithFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY)]].mechFlags & TM_STAND_IN_TILE) ? "in" : "on", + sprintf(newText, "%s is trapped %s %s.\n ", capMonstName, (tileCatalog[pmapAt(monst->loc)->layers[layerWithFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY)]].mechFlags & TM_STAND_IN_TILE) ? "in" : "on", tileCatalog[pmapAt(monst->loc)->layers[layerWithFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY)]].description); strcat(buf, newText); } @@ -4229,11 +3826,7 @@ void monsterDetails(char buf[], creature *monst) { // Combat info for the monster attacking the player if ((monst->info.flags & MONST_RESTRICTED_TO_LIQUID) && !cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING)) { sprintf(newText, " %s writhes helplessly on dry land.\n ", capMonstName); - } else if (rogue.armor - && (rogue.armor->flags & ITEM_RUNIC) - && (rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) - && rogue.armor->enchant2 == A_IMMUNITY - && monsterIsInClass(monst, rogue.armor->vorpalEnemy)) { + } else if (rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && (rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) && rogue.armor->enchant2 == A_IMMUNITY && monsterIsInClass(monst, rogue.armor->vorpalEnemy)) { itemName(rogue.armor, theItemName, false, false, NULL); sprintf(newText, "Your %s renders you immune to %s.\n ", theItemName, monstName); @@ -4249,30 +3842,23 @@ void monsterDetails(char buf[], creature *monst) { } if (i == 0) { // Already fatally poisoned. - sprintf(newText, "%s has a %i%% chance to poison you and typically poisons for %i turns.\n ", - capMonstName, - combatMath2, - (int) ((monst->info.damage.lowerBound + monst->info.damage.upperBound) * monsterDamageAdjustmentAmount(monst) / 2 / FP_FACTOR)); + sprintf(newText, "%s has a %i%% chance to poison you and typically poisons for %i turns.\n ", capMonstName, combatMath2, + (int)((monst->info.damage.lowerBound + monst->info.damage.upperBound) * monsterDamageAdjustmentAmount(monst) / 2 / FP_FACTOR)); } else { - sprintf(newText, "%s has a %i%% chance to poison you, typically poisons for %i turns, and at worst, could fatally poison you in %i hit%s.\n ", - capMonstName, - combatMath2, - (int) ((monst->info.damage.lowerBound + monst->info.damage.upperBound) * monsterDamageAdjustmentAmount(monst) / 2 / FP_FACTOR), - i, - (i > 1 ? "s" : "")); + sprintf(newText, + "%s has a %i%% chance to poison you, typically poisons for %i turns, and at worst, could " + "fatally poison you in %i hit%s.\n ", + capMonstName, combatMath2, (int)((monst->info.damage.lowerBound + monst->info.damage.upperBound) * monsterDamageAdjustmentAmount(monst) / 2 / FP_FACTOR), i, (i > 1 ? "s" : "")); } } else { - combatMath = ((player.currentHP + (monst->info.damage.upperBound * monsterDamageAdjustmentAmount(monst) / FP_FACTOR) - 1) * FP_FACTOR) - / (monst->info.damage.upperBound * monsterDamageAdjustmentAmount(monst)); + combatMath = ((player.currentHP + (monst->info.damage.upperBound * monsterDamageAdjustmentAmount(monst) / FP_FACTOR) - 1) * FP_FACTOR) / (monst->info.damage.upperBound * monsterDamageAdjustmentAmount(monst)); if (combatMath < 1) { combatMath = 1; } - sprintf(newText, "%s has a %i%% chance to hit you, typically hits for %i%% of your current health, and at worst, could defeat you in %i hit%s.\n ", - capMonstName, - combatMath2, - (int) (100 * (monst->info.damage.lowerBound + monst->info.damage.upperBound) * monsterDamageAdjustmentAmount(monst) / 2 / player.currentHP / FP_FACTOR), - combatMath, - (combatMath > 1 ? "s" : "")); + sprintf(newText, + "%s has a %i%% chance to hit you, typically hits for %i%% of your current health, and at worst, " + "could defeat you in %i hit%s.\n ", + capMonstName, combatMath2, (int)(100 * (monst->info.damage.lowerBound + monst->info.damage.upperBound) * monsterDamageAdjustmentAmount(monst) / 2 / player.currentHP / FP_FACTOR), combatMath, (combatMath > 1 ? "s" : "")); } } upperCase(newText); @@ -4296,11 +3882,7 @@ void monsterDetails(char buf[], creature *monst) { i = encodeMessageColor(buf, i, &white); sprintf(newText, "You deal no direct damage."); - } else if (rogue.weapon - && (rogue.weapon->flags & ITEM_RUNIC) - && (rogue.weapon->flags & ITEM_RUNIC_IDENTIFIED) - && rogue.weapon->enchant2 == W_SLAYING - && monsterIsInClass(monst, rogue.weapon->vorpalEnemy)) { + } else if (rogue.weapon && (rogue.weapon->flags & ITEM_RUNIC) && (rogue.weapon->flags & ITEM_RUNIC_IDENTIFIED) && rogue.weapon->enchant2 == W_SLAYING && monsterIsInClass(monst, rogue.weapon->vorpalEnemy)) { i = strlen(buf); i = encodeMessageColor(buf, i, &goodMessageColor); @@ -4331,12 +3913,10 @@ void monsterDetails(char buf[], creature *monst) { } else { combatMath2 = hitProbability(&player, monst); } - sprintf(newText, "You have a %i%% chance to hit %s, typically hit for %i%% of $HISHER current health, and at best, could defeat $HIMHER in %i hit%s.", - combatMath2, - monstName, - 100 * playerKnownAverageDamage / monst->currentHP, - combatMath, - (combatMath > 1 ? "s" : "")); + sprintf(newText, + "You have a %i%% chance to hit %s, typically hit for %i%% of $HISHER current health, and at best, " + "could defeat $HIMHER in %i hit%s.", + combatMath2, monstName, 100 * playerKnownAverageDamage / monst->currentHP, combatMath, (combatMath > 1 ? "s" : "")); } upperCase(newText); strcat(buf, newText); @@ -4437,9 +4017,8 @@ void monsterDetails(char buf[], creature *monst) { } // ability flags - for (i=0; i<32; i++) { - if ((monst->info.abilityFlags & (Fl(i))) - && monsterAbilityFlagDescriptions[i][0]) { + for (i = 0; i < 32; i++) { + if ((monst->info.abilityFlags & (Fl(i))) && monsterAbilityFlagDescriptions[i][0]) { if (anyFlags) { strcat(newText, "& "); commaCount++; @@ -4450,9 +4029,8 @@ void monsterDetails(char buf[], creature *monst) { } // behavior flags - for (i=0; i<32; i++) { - if ((monst->info.flags & (Fl(i))) - && monsterBehaviorFlagDescriptions[i][0]) { + for (i = 0; i < 32; i++) { + if ((monst->info.flags & (Fl(i))) && monsterBehaviorFlagDescriptions[i][0]) { if (anyFlags) { strcat(newText, "& "); commaCount++; @@ -4463,9 +4041,8 @@ void monsterDetails(char buf[], creature *monst) { } // bookkeeping flags - for (i=0; i<32; i++) { - if ((monst->bookkeepingFlags & (Fl(i))) - && monsterBookkeepingFlagDescriptions[i][0]) { + for (i = 0; i < 32; i++) { + if ((monst->bookkeepingFlags & (Fl(i))) && monsterBookkeepingFlagDescriptions[i][0]) { if (anyFlags) { strcat(newText, "& "); commaCount++; @@ -4477,9 +4054,9 @@ void monsterDetails(char buf[], creature *monst) { if (anyFlags) { strcat(newText, ". "); - //strcat(buf, "\n\n"); + // strcat(buf, "\n\n"); j = strlen(buf); - for (i=0; newText[i] != '\0'; i++) { + for (i = 0; newText[i] != '\0'; i++) { if (newText[i] == '&') { if (!--commaCount) { buf[j] = '\0'; diff --git a/src/brogue/Movement.c b/src/brogue/Movement.c index 6c56d95b..376e036e 100644 --- a/src/brogue/Movement.c +++ b/src/brogue/Movement.c @@ -49,9 +49,8 @@ void playerRuns(short direction) { } else if (direction < 4) { for (int dir = 0; dir < 4; dir++) { const pos newLoc = posNeighborInDirection(player.loc, dir); - if (cardinalPassability[dir] != monsterAvoids(&player, newLoc) - && !posEq(player.loc, posNeighborInDirection(newLoc, direction))) { - // dir is not the x-opposite or y-opposite of direction + if (cardinalPassability[dir] != monsterAvoids(&player, newLoc) && !posEq(player.loc, posNeighborInDirection(newLoc, direction))) { + // dir is not the x-opposite or y-opposite of direction rogue.disturbed = true; } } @@ -99,14 +98,10 @@ enum dungeonLayers layerWithFlag(short x, short y, unsigned long flag) { } // Retrieves a pointer to the flavor text of the highest-priority terrain at the given location -const char *tileFlavor(short x, short y) { - return tileCatalog[pmap[x][y].layers[highestPriorityLayer(x, y, false)]].flavorText; -} +const char *tileFlavor(short x, short y) { return tileCatalog[pmap[x][y].layers[highestPriorityLayer(x, y, false)]].flavorText; } // Retrieves a pointer to the description text of the highest-priority terrain at the given location -const char *tileText(short x, short y) { - return tileCatalog[pmap[x][y].layers[highestPriorityLayer(x, y, false)]].description; -} +const char *tileText(short x, short y) { return tileCatalog[pmap[x][y].layers[highestPriorityLayer(x, y, false)]].description; } void describedItemBasedOnParameters(short theCategory, short theKind, short theQuantity, short theOriginDepth, char *buf) { item *tempItem = initializeItem(); @@ -160,22 +155,17 @@ void describeLocation(char *buf, short x, short y) { theItem = itemAtLoc(x, y); monsterDormant = false; if (pmap[x][y].flags & HAS_MONSTER) { - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); } else if (pmap[x][y].flags & HAS_DORMANT_MONSTER) { - monst = dormantMonsterAtLoc((pos){ x, y }); + monst = dormantMonsterAtLoc((pos){x, y}); monsterDormant = true; } // detecting magical items magicItem = NULL; - if (theItem && !playerCanSeeOrSense(x, y) - && (theItem->flags & ITEM_MAGIC_DETECTED) - && itemMagicPolarity(theItem)) { + if (theItem && !playerCanSeeOrSense(x, y) && (theItem->flags & ITEM_MAGIC_DETECTED) && itemMagicPolarity(theItem)) { magicItem = theItem; - } else if (monst && !canSeeMonster(monst) - && monst->carriedItem - && (monst->carriedItem->flags & ITEM_MAGIC_DETECTED) - && itemMagicPolarity(monst->carriedItem)) { + } else if (monst && !canSeeMonster(monst) && monst->carriedItem && (monst->carriedItem->flags & ITEM_MAGIC_DETECTED) && itemMagicPolarity(monst->carriedItem)) { magicItem = monst->carriedItem; } if (magicItem && !(pmap[x][y].flags & DISCOVERED)) { @@ -196,12 +186,9 @@ void describeLocation(char *buf, short x, short y) { } // telepathy - if (monst - && !canSeeMonster(monst) - && monsterRevealed(monst)) { + if (monst && !canSeeMonster(monst) && monsterRevealed(monst)) { - strcpy(adjective, (((!player.status[STATUS_HALLUCINATING] || rogue.playbackOmniscience) && !monst->info.isLarge) - || (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience && rand_range(0, 1)) ? "small" : "large")); + strcpy(adjective, (((!player.status[STATUS_HALLUCINATING] || rogue.playbackOmniscience) && !monst->info.isLarge) || (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience && rand_range(0, 1)) ? "small" : "large")); if (pmap[x][y].flags & DISCOVERED) { strcpy(object, tileText(x, y)); if (monst->bookkeepingFlags & MB_SUBMERGED) { @@ -234,8 +221,7 @@ void describeLocation(char *buf, short x, short y) { if (player.status[STATUS_HALLUCINATING] && !rogue.playbackOmniscience) { describeHallucinatedItem(object); } else { - describedItemBasedOnParameters(pmap[x][y].rememberedItemCategory, pmap[x][y].rememberedItemKind, - pmap[x][y].rememberedItemQuantity, pmap[x][y].rememberedItemOriginDepth, object); + describedItemBasedOnParameters(pmap[x][y].rememberedItemCategory, pmap[x][y].rememberedItemKind, pmap[x][y].rememberedItemQuantity, pmap[x][y].rememberedItemOriginDepth, object); } } else { strcpy(object, tileCatalog[pmap[x][y].rememberedTerrain].description); @@ -263,12 +249,8 @@ void describeLocation(char *buf, short x, short y) { return; } - subjectMoving = (monst->turnsSpentStationary == 0 - && !(monst->info.flags & (MONST_GETS_TURN_ON_ACTIVATION | MONST_IMMOBILE)) - && monst->creatureState != MONSTER_SLEEPING - && !(monst->bookkeepingFlags & (MB_SEIZED | MB_CAPTIVE))); - if ((monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) - && cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) { + subjectMoving = (monst->turnsSpentStationary == 0 && !(monst->info.flags & (MONST_GETS_TURN_ON_ACTIVATION | MONST_IMMOBILE)) && monst->creatureState != MONSTER_SLEEPING && !(monst->bookkeepingFlags & (MB_SEIZED | MB_CAPTIVE))); + if ((monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) && cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) { strcpy(verb, "is embedded"); } else if (cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) { strcpy(verb, "is trapped"); @@ -297,8 +279,7 @@ void describeLocation(char *buf, short x, short y) { subjectMoving = false; } else if (monst->status[STATUS_CONFUSED]) { strcpy(verb, "is staggering"); - } else if ((monst->info.flags & MONST_RESTRICTED_TO_LIQUID) - && !cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING)) { + } else if ((monst->info.flags & MONST_RESTRICTED_TO_LIQUID) && !cellHasTMFlag(monst->loc.x, monst->loc.y, TM_ALLOWS_SUBMERGING)) { strcpy(verb, "is lying"); subjectMoving = false; } else if (monst->info.flags & MONST_IMMOBILE) { @@ -335,12 +316,10 @@ void describeLocation(char *buf, short x, short y) { describedItemName(theItem, object); } else { if (!prepositionLocked) { - strcpy(preposition, subjectMoving ? (standsInTerrain ? "through" : "across") - : (standsInTerrain ? "in" : "on")); + strcpy(preposition, subjectMoving ? (standsInTerrain ? "through" : "across") : (standsInTerrain ? "in" : "on")); } strcpy(object, tileText(x, y)); - } } else { // no monster strcpy(object, tileText(x, y)); @@ -357,9 +336,7 @@ void describeLocation(char *buf, short x, short y) { } else { strcat(verb, subjectMoving ? " drifting" : " lying"); } - strcpy(preposition, standsInTerrain ? (subjectMoving ? "through" : "in") - : (subjectMoving ? "across" : "on")); - + strcpy(preposition, standsInTerrain ? (subjectMoving ? "through" : "in") : (subjectMoving ? "across" : "on")); } else { // no item sprintf(buf, "you %s %s.", (playerCanDirectlySee(x, y) ? "see" : "sense"), object); @@ -373,7 +350,7 @@ void describeLocation(char *buf, short x, short y) { } void printLocationDescription(short x, short y) { - char buf[DCOLS*3]; + char buf[DCOLS * 3]; describeLocation(buf, x, y); flavorMessage(buf); } @@ -387,8 +364,7 @@ void useKeyAt(item *theItem, short x, short y) { strcpy(terrainName, "unknown terrain"); // redundant failsafe for (layer = 0; layer < NUMBER_TERRAIN_LAYERS; layer++) { if (tileCatalog[pmap[x][y].layers[layer]].mechFlags & TM_PROMOTES_WITH_KEY) { - if (tileCatalog[pmap[x][y].layers[layer]].description[0] == 'a' - && tileCatalog[pmap[x][y].layers[layer]].description[1] == ' ') { + if (tileCatalog[pmap[x][y].layers[layer]].description[0] == 'a' && tileCatalog[pmap[x][y].layers[layer]].description[1] == ' ') { sprintf(terrainName, "the %s", &(tileCatalog[pmap[x][y].layers[layer]].description[2])); } else { strcpy(terrainName, tileCatalog[pmap[x][y].layers[layer]].description); @@ -403,7 +379,7 @@ void useKeyAt(item *theItem, short x, short y) { } disposable = false; - for (i=0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++) { + for (i = 0; i < KEY_ID_MAXIMUM && (theItem->keyLoc[i].x || theItem->keyLoc[i].machine); i++) { if (theItem->keyLoc[i].x == x && theItem->keyLoc[i].y == y && theItem->keyLoc[i].disposableHere) { disposable = true; } else if (theItem->keyLoc[i].machine == pmap[x][y].machineNumber && theItem->keyLoc[i].disposableHere) { @@ -414,17 +390,14 @@ void useKeyAt(item *theItem, short x, short y) { if (disposable) { if (removeItemFromChain(theItem, packItems)) { itemName(theItem, buf2, true, false, NULL); - sprintf(buf, "you use your %s %s %s.", - buf2, - preposition, - terrainName); + sprintf(buf, "you use your %s %s %s.", buf2, preposition, terrainName); messageWithColor(buf, &itemMessageColor, 0); deleteItem(theItem); } else if (removeItemFromChain(theItem, floorItems)) { deleteItem(theItem); pmap[x][y].flags &= ~HAS_ITEM; } else if (pmap[x][y].flags & HAS_MONSTER) { - monst = monsterAtLoc((pos){ x, y }); + monst = monsterAtLoc((pos){x, y}); if (monst->carriedItem && monst->carriedItem == theItem) { monst->carriedItem = NULL; deleteItem(theItem); @@ -437,15 +410,11 @@ short randValidDirectionFrom(creature *monst, short x, short y, boolean respectA short i, newX, newY, validDirections[8], count = 0; brogueAssert(rogue.RNG == RNG_SUBSTANTIVE); - for (i=0; i<8; i++) { + for (i = 0; i < 8; i++) { newX = x + nbDirs[i][0]; newY = y + nbDirs[i][1]; - if (coordinatesAreInMap(newX, newY) - && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) - && !diagonalBlocked(x, y, newX, newY, false) - && (!respectAvoidancePreferences - || (!monsterAvoids(monst, (pos){newX, newY})) - || ((pmap[newX][newY].flags & HAS_PLAYER) && monst->creatureState != MONSTER_ALLY))) { + if (coordinatesAreInMap(newX, newY) && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) && !diagonalBlocked(x, y, newX, newY, false) + && (!respectAvoidancePreferences || (!monsterAvoids(monst, (pos){newX, newY})) || ((pmap[newX][newY].flags & HAS_PLAYER) && monst->creatureState != MONSTER_ALLY))) { validDirections[count++] = i; } } @@ -460,8 +429,7 @@ void vomit(creature *monst) { char buf[COLS], monstName[COLS]; spawnDungeonFeature(monst->loc.x, monst->loc.y, &dungeonFeatureCatalog[DF_VOMIT], true, false); - if (canDirectlySeeMonster(monst) - && !rogue.automationActive) { + if (canDirectlySeeMonster(monst) && !rogue.automationActive) { monsterName(monstName, monst, true); sprintf(buf, "%s vomit%s profusely", monstName, (monst == &player ? "" : "s")); @@ -474,10 +442,7 @@ void moveEntrancedMonsters(enum directions dir) { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); - if (monst->status[STATUS_ENTRANCED] - && !monst->status[STATUS_STUCK] - && !monst->status[STATUS_PARALYZED] - && !(monst->bookkeepingFlags & MB_CAPTIVE)) { + if (monst->status[STATUS_ENTRANCED] && !monst->status[STATUS_STUCK] && !monst->status[STATUS_PARALYZED] && !(monst->bookkeepingFlags & MB_CAPTIVE)) { moveMonster(monst, nbDirs[dir][0], nbDirs[dir][1]); } @@ -515,10 +480,8 @@ boolean freeCaptivesEmbeddedAt(short x, short y) { if (pmap[x][y].flags & HAS_MONSTER) { // Free any captives trapped in the tunnelized terrain. - monst = monsterAtLoc((pos){ x, y }); - if ((monst->bookkeepingFlags & MB_CAPTIVE) - && !(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) - && (cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY))) { + monst = monsterAtLoc((pos){x, y}); + if ((monst->bookkeepingFlags & MB_CAPTIVE) && !(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) && (cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY))) { freeCaptive(monst); return true; } @@ -530,21 +493,13 @@ boolean freeCaptivesEmbeddedAt(short x, short y) { boolean abortAttackAgainstAcidicTarget(creature *hitList[8]) { short i; char monstName[COLS], weaponName[COLS]; - char buf[COLS*3]; - - if (rogue.weapon - && !(rogue.weapon->flags & ITEM_PROTECTED) - && !player.status[STATUS_HALLUCINATING] - && !player.status[STATUS_CONFUSED]) { - - for (i=0; i<8; i++) { - if (hitList[i] - && (hitList[i]->info.flags & MONST_DEFEND_DEGRADE_WEAPON) - && canSeeMonster(hitList[i]) - && (!(rogue.weapon->flags & ITEM_RUNIC) - || !(rogue.weapon->flags & ITEM_RUNIC_IDENTIFIED) - || rogue.weapon->enchant2 != W_SLAYING - || !monsterIsInClass(hitList[i], rogue.weapon->vorpalEnemy))) { + char buf[COLS * 3]; + + if (rogue.weapon && !(rogue.weapon->flags & ITEM_PROTECTED) && !player.status[STATUS_HALLUCINATING] && !player.status[STATUS_CONFUSED]) { + + for (i = 0; i < 8; i++) { + if (hitList[i] && (hitList[i]->info.flags & MONST_DEFEND_DEGRADE_WEAPON) && canSeeMonster(hitList[i]) + && (!(rogue.weapon->flags & ITEM_RUNIC) || !(rogue.weapon->flags & ITEM_RUNIC_IDENTIFIED) || rogue.weapon->enchant2 != W_SLAYING || !monsterIsInClass(hitList[i], rogue.weapon->vorpalEnemy))) { monsterName(monstName, hitList[i], true); itemName(rogue.weapon, weaponName, false, false, NULL); @@ -586,10 +541,7 @@ boolean handleWhipAttacks(creature *attacker, enum directions dir, boolean *abor getImpactLoc(&strikeLoc, originLoc, targetLoc, 5, false, &boltCatalog[BOLT_WHIP]); defender = monsterAtLoc(strikeLoc); - if (defender - && (attacker != &player || canSeeMonster(defender)) - && !monsterIsHidden(defender, attacker) - && monsterWillAttackTarget(attacker, defender)) { + if (defender && (attacker != &player || canSeeMonster(defender)) && !monsterIsHidden(defender, attacker) && monsterWillAttackTarget(attacker, defender)) { if (attacker == &player) { hitList[0] = defender; @@ -632,10 +584,7 @@ boolean handleSpearAttacks(creature *attacker, enum directions dir, boolean *abo } for (i = 0; i < range; i++) { - const pos targetLoc = (pos) { - attacker->loc.x + (1 + i) * nbDirs[dir][0], - attacker->loc.y + (1 + i) * nbDirs[dir][1] - }; + const pos targetLoc = (pos){attacker->loc.x + (1 + i) * nbDirs[dir][0], attacker->loc.y + (1 + i) * nbDirs[dir][1]}; if (!isPosInMap(targetLoc)) { break; } @@ -644,18 +593,14 @@ boolean handleSpearAttacks(creature *attacker, enum directions dir, boolean *abo hitlist. Any of those that are either right by us or visible will trigger the attack. */ defender = monsterAtLoc(targetLoc); - if (defender - && (!cellHasTerrainFlag(targetLoc.x, targetLoc.y, T_OBSTRUCTS_PASSABILITY) - || (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) - && monsterWillAttackTarget(attacker, defender)) { + if (defender && (!cellHasTerrainFlag(targetLoc.x, targetLoc.y, T_OBSTRUCTS_PASSABILITY) || (defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) && monsterWillAttackTarget(attacker, defender)) { hitList[h++] = defender; /* We check if i=0, i.e. the defender is right next to us, because we have to do "normal" attacking here. We can't just return false and leave to playerMoves/moveMonster due to the collateral hitlist. */ - if (i == 0 || !monsterIsHidden(defender, attacker) - && (attacker != &player || canSeeMonster(defender))) { + if (i == 0 || !monsterIsHidden(defender, attacker) && (attacker != &player || canSeeMonster(defender))) { // We'll attack. proceed = true; } @@ -677,12 +622,8 @@ boolean handleSpearAttacks(creature *attacker, enum directions dir, boolean *abo } if (!rogue.playbackFastForward) { for (i = 0; i < range; i++) { - const pos targetLoc = (pos) { - attacker->loc.x + (1 + i) * nbDirs[dir][0], - attacker->loc.y + (1 + i) * nbDirs[dir][1] - }; - if (isPosInMap(targetLoc) - && playerCanSeeOrSense(targetLoc.x, targetLoc.y)) { + const pos targetLoc = (pos){attacker->loc.x + (1 + i) * nbDirs[dir][0], attacker->loc.y + (1 + i) * nbDirs[dir][1]}; + if (isPosInMap(targetLoc) && playerCanSeeOrSense(targetLoc.x, targetLoc.y)) { visualEffect = true; plotForegroundChar(boltChar[dir], targetLoc.x, targetLoc.y, &lightBlue, true); @@ -698,10 +639,7 @@ boolean handleSpearAttacks(creature *attacker, enum directions dir, boolean *abo if (visualEffect) { pauseAnimation(16); for (i = 0; i < range; i++) { - const pos targetLoc = (pos) { - attacker->loc.x + (1 + i) * nbDirs[dir][0], - attacker->loc.y + (1 + i) * nbDirs[dir][1] - }; + const pos targetLoc = (pos){attacker->loc.x + (1 + i) * nbDirs[dir][0], attacker->loc.y + (1 + i) * nbDirs[dir][1]}; if (isPosInMap(targetLoc)) { refreshDungeonCell(targetLoc.x, targetLoc.y); } @@ -720,13 +658,8 @@ void buildFlailHitList(const short x, const short y, const short newX, const sho creature *monst = nextCreature(&it); mx = monst->loc.x; my = monst->loc.y; - if (distanceBetween((pos){x, y}, (pos){mx, my}) == 1 - && distanceBetween((pos){newX, newY}, (pos){mx, my}) == 1 - && canSeeMonster(monst) - && monstersAreEnemies(&player, monst) - && monst->creatureState != MONSTER_ALLY - && !(monst->bookkeepingFlags & MB_IS_DYING) - && (!cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY) || (monst->info.flags & MONST_ATTACKABLE_THRU_WALLS))) { + if (distanceBetween((pos){x, y}, (pos){mx, my}) == 1 && distanceBetween((pos){newX, newY}, (pos){mx, my}) == 1 && canSeeMonster(monst) && monstersAreEnemies(&player, monst) && monst->creatureState != MONSTER_ALLY + && !(monst->bookkeepingFlags & MB_IS_DYING) && (!cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY) || (monst->info.flags & MONST_ATTACKABLE_THRU_WALLS))) { while (hitList[i]) { i++; @@ -761,7 +694,7 @@ boolean playerMoves(short direction) { boolean playerMoved = false, specialAttackAborted = false, anyAttackHit = false; creature *defender = NULL, *tempMonst = NULL, *hitList[16] = {NULL}; char monstName[COLS]; - char buf[COLS*3]; + char buf[COLS * 3]; const int directionKeys[8] = {UP_KEY, DOWN_KEY, LEFT_KEY, RIGHT_KEY, UPLEFT_KEY, DOWNLEFT_KEY, UPRIGHT_KEY, DOWNRIGHT_KEY}; brogueAssert(direction >= 0 && direction < DIRECTION_COUNT); @@ -778,21 +711,16 @@ boolean playerMoves(short direction) { boolean committed = false; // as long as this is false, the keystroke can be cancelled if (player.status[STATUS_CONFUSED]) { - // Confirmation dialog if you're moving while confused and you're next to lava and not levitating or immune to fire. - if (player.status[STATUS_LEVITATING] <= 1 - && player.status[STATUS_IMMUNE_TO_FIRE] <= 1) { + // Confirmation dialog if you're moving while confused and you're next to lava and not levitating or immune to + // fire. + if (player.status[STATUS_LEVITATING] <= 1 && player.status[STATUS_IMMUNE_TO_FIRE] <= 1) { - for (i=0; i<8; i++) { + for (i = 0; i < 8; i++) { newestX = x + nbDirs[i][0]; newestY = y + nbDirs[i][1]; - if (coordinatesAreInMap(newestX, newestY) - && (pmap[newestX][newestY].flags & (DISCOVERED | MAGIC_MAPPED)) - && !diagonalBlocked(x, y, newestX, newestY, false) - && cellHasTerrainFlag(newestX, newestY, T_LAVA_INSTA_DEATH) + if (coordinatesAreInMap(newestX, newestY) && (pmap[newestX][newestY].flags & (DISCOVERED | MAGIC_MAPPED)) && !diagonalBlocked(x, y, newestX, newestY, false) && cellHasTerrainFlag(newestX, newestY, T_LAVA_INSTA_DEATH) && !cellHasTerrainFlag(newestX, newestY, T_OBSTRUCTS_PASSABILITY | T_ENTANGLES) - && !((pmap[newestX][newestY].flags & HAS_MONSTER) - && canSeeMonster(monsterAtLoc((pos){ newestX, newestY })) - && monsterAtLoc((pos){ newestX, newestY })->creatureState != MONSTER_ALLY)) { + && !((pmap[newestX][newestY].flags & HAS_MONSTER) && canSeeMonster(monsterAtLoc((pos){newestX, newestY})) && monsterAtLoc((pos){newestX, newestY})->creatureState != MONSTER_ALLY)) { if (!confirm("Risk stumbling into lava?", false)) { cancelKeystroke(); @@ -820,13 +748,11 @@ boolean playerMoves(short direction) { } if (pmap[newX][newY].flags & HAS_MONSTER) { - defender = monsterAtLoc((pos){ newX, newY }); + defender = monsterAtLoc((pos){newX, newY}); } // If there's no enemy at the movement location that the player is aware of, consider terrain promotions. - if (!defender - || (!canSeeMonster(defender) && !monsterRevealed(defender)) - || !monstersAreEnemies(&player, defender)) { + if (!defender || (!canSeeMonster(defender) && !monsterRevealed(defender)) || !monstersAreEnemies(&player, defender)) { if (cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) && cellHasTMFlag(newX, newY, TM_PROMOTES_ON_PLAYER_ENTRY)) { layer = layerWithTMFlag(newX, newY, TM_PROMOTES_ON_PLAYER_ENTRY); @@ -838,17 +764,14 @@ boolean playerMoves(short direction) { return true; } } - } - if (((!cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) || (cellHasTMFlag(newX, newY, TM_PROMOTES_WITH_KEY) && keyInPackFor(newX, newY))) - && !diagonalBlocked(x, y, newX, newY, false) + if (((!cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY) || (cellHasTMFlag(newX, newY, TM_PROMOTES_WITH_KEY) && keyInPackFor(newX, newY))) && !diagonalBlocked(x, y, newX, newY, false) && (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY) || (cellHasTMFlag(x, y, TM_PROMOTES_WITH_KEY) && keyInPackFor(x, y)))) || (defender && defender->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { // if the move is not blocked - if (handleWhipAttacks(&player, direction, &specialAttackAborted) - || handleSpearAttacks(&player, direction, &specialAttackAborted)) { + if (handleWhipAttacks(&player, direction, &specialAttackAborted) || handleSpearAttacks(&player, direction, &specialAttackAborted)) { committed = true; playerRecoversFromAttacking(true); @@ -885,11 +808,10 @@ boolean playerMoves(short direction) { if (defender->creatureState != MONSTER_ALLY) { // Make a hit list of monsters the player is attacking this turn. - // We separate this tallying phase from the actual attacking phase because sometimes the attacks themselves - // create more monsters, and those shouldn't be attacked in the same turn. + // We separate this tallying phase from the actual attacking phase because sometimes the attacks + // themselves create more monsters, and those shouldn't be attacked in the same turn. - buildHitList(hitList, &player, defender, - rogue.weapon && (rogue.weapon->flags & ITEM_ATTACKS_ALL_ADJACENT)); + buildHitList(hitList, &player, defender, rogue.weapon && (rogue.weapon->flags & ITEM_ATTACKS_ALL_ADJACENT)); if (abortAttackAgainstAcidicTarget(hitList)) { // Acid mound attack confirmation. brogueAssert(!committed); @@ -911,11 +833,8 @@ boolean playerMoves(short direction) { committed = true; // Attack! - for (i=0; i<16; i++) { - if (hitList[i] - && monsterWillAttackTarget(&player, hitList[i]) - && !(hitList[i]->bookkeepingFlags & MB_IS_DYING) - && !rogue.gameHasEnded) { + for (i = 0; i < 16; i++) { + if (hitList[i] && monsterWillAttackTarget(&player, hitList[i]) && !(hitList[i]->bookkeepingFlags & MB_IS_DYING) && !rogue.gameHasEnded) { if (attack(&player, hitList[i], false)) { anyAttackHit = true; @@ -933,11 +852,8 @@ boolean playerMoves(short direction) { if (player.bookkeepingFlags & MB_SEIZED) { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *tempMonst = nextCreature(&it); - if ((tempMonst->bookkeepingFlags & MB_SEIZING) - && monstersAreEnemies(&player, tempMonst) - && distanceBetween(player.loc, tempMonst->loc) == 1 - && !diagonalBlocked(player.loc.x, player.loc.y, tempMonst->loc.x, tempMonst->loc.y, false) - && !tempMonst->status[STATUS_ENTRANCED]) { + if ((tempMonst->bookkeepingFlags & MB_SEIZING) && monstersAreEnemies(&player, tempMonst) && distanceBetween(player.loc, tempMonst->loc) == 1 + && !diagonalBlocked(player.loc.x, player.loc.y, tempMonst->loc.x, tempMonst->loc.y, false) && !tempMonst->status[STATUS_ENTRANCED]) { monsterName(monstName, tempMonst, true); if (committed || !canSeeMonster(tempMonst)) { @@ -958,63 +874,38 @@ boolean playerMoves(short direction) { player.bookkeepingFlags &= ~MB_SEIZED; // failsafe } - if (pmap[newX][newY].flags & (DISCOVERED | MAGIC_MAPPED) - && player.status[STATUS_LEVITATING] <= 1 - && !player.status[STATUS_CONFUSED] - && cellHasTerrainFlag(newX, newY, T_LAVA_INSTA_DEATH) - && player.status[STATUS_IMMUNE_TO_FIRE] <= 1 - && !cellHasTerrainFlag(newX, newY, T_ENTANGLES) - && !cellHasTMFlag(newX, newY, TM_IS_SECRET)) { + if (pmap[newX][newY].flags & (DISCOVERED | MAGIC_MAPPED) && player.status[STATUS_LEVITATING] <= 1 && !player.status[STATUS_CONFUSED] && cellHasTerrainFlag(newX, newY, T_LAVA_INSTA_DEATH) && player.status[STATUS_IMMUNE_TO_FIRE] <= 1 + && !cellHasTerrainFlag(newX, newY, T_ENTANGLES) && !cellHasTMFlag(newX, newY, TM_IS_SECRET)) { message("that would be certain death!", 0); brogueAssert(!committed); cancelKeystroke(); return false; // player won't willingly step into lava - } else if (pmap[newX][newY].flags & (DISCOVERED | MAGIC_MAPPED) - && player.status[STATUS_LEVITATING] <= 1 - && !player.status[STATUS_CONFUSED] - && cellHasTerrainFlag(newX, newY, T_AUTO_DESCENT) - && (!cellHasTerrainFlag(newX, newY, T_ENTANGLES) || cellHasTMFlag(newX, newY, TM_PROMOTES_ON_PLAYER_ENTRY)) - && !cellHasTMFlag(newX, newY, TM_IS_SECRET) - && !confirm("Dive into the depths?", false)) { + } else if (pmap[newX][newY].flags & (DISCOVERED | MAGIC_MAPPED) && player.status[STATUS_LEVITATING] <= 1 && !player.status[STATUS_CONFUSED] && cellHasTerrainFlag(newX, newY, T_AUTO_DESCENT) + && (!cellHasTerrainFlag(newX, newY, T_ENTANGLES) || cellHasTMFlag(newX, newY, TM_PROMOTES_ON_PLAYER_ENTRY)) && !cellHasTMFlag(newX, newY, TM_IS_SECRET) && !confirm("Dive into the depths?", false)) { brogueAssert(!committed); cancelKeystroke(); return false; - } else if (playerCanSee(newX, newY) - && !player.status[STATUS_CONFUSED] - && !player.status[STATUS_BURNING] - && player.status[STATUS_IMMUNE_TO_FIRE] <= 1 - && cellHasTerrainFlag(newX, newY, T_IS_FIRE) - && !cellHasTMFlag(newX, newY, TM_EXTINGUISHES_FIRE) - && !confirm("Venture into flame?", false)) { + } else if (playerCanSee(newX, newY) && !player.status[STATUS_CONFUSED] && !player.status[STATUS_BURNING] && player.status[STATUS_IMMUNE_TO_FIRE] <= 1 && cellHasTerrainFlag(newX, newY, T_IS_FIRE) + && !cellHasTMFlag(newX, newY, TM_EXTINGUISHES_FIRE) && !confirm("Venture into flame?", false)) { brogueAssert(!committed); cancelKeystroke(); return false; - } else if (playerCanSee(newX, newY) - && !player.status[STATUS_CONFUSED] - && !player.status[STATUS_BURNING] - && cellHasTerrainFlag(newX, newY, T_CAUSES_CONFUSION | T_CAUSES_PARALYSIS) - && (!rogue.armor || !(rogue.armor->flags & ITEM_RUNIC) || !(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) || rogue.armor->enchant2 != A_RESPIRATION) - && !confirm("Venture into dangerous gas?", false)) { + } else if (playerCanSee(newX, newY) && !player.status[STATUS_CONFUSED] && !player.status[STATUS_BURNING] && cellHasTerrainFlag(newX, newY, T_CAUSES_CONFUSION | T_CAUSES_PARALYSIS) + && (!rogue.armor || !(rogue.armor->flags & ITEM_RUNIC) || !(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) || rogue.armor->enchant2 != A_RESPIRATION) && !confirm("Venture into dangerous gas?", false)) { brogueAssert(!committed); cancelKeystroke(); return false; - } else if (pmap[newX][newY].flags & (ANY_KIND_OF_VISIBLE | MAGIC_MAPPED) - && player.status[STATUS_LEVITATING] <= 1 - && !player.status[STATUS_CONFUSED] - && cellHasTerrainFlag(newX, newY, T_IS_DF_TRAP) - && !(pmap[newX][newY].flags & PRESSURE_PLATE_DEPRESSED) - && !cellHasTMFlag(newX, newY, TM_IS_SECRET) - && (!rogue.armor || !(rogue.armor->flags & ITEM_RUNIC) || !(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) || rogue.armor->enchant2 != A_RESPIRATION || - (!cellHasTerrainType(newX, newY, GAS_TRAP_POISON) - && !cellHasTerrainType(newX, newY, GAS_TRAP_PARALYSIS) - && !cellHasTerrainType(newX, newY, GAS_TRAP_CONFUSION))) + } else if (pmap[newX][newY].flags & (ANY_KIND_OF_VISIBLE | MAGIC_MAPPED) && player.status[STATUS_LEVITATING] <= 1 && !player.status[STATUS_CONFUSED] && cellHasTerrainFlag(newX, newY, T_IS_DF_TRAP) + && !(pmap[newX][newY].flags & PRESSURE_PLATE_DEPRESSED) && !cellHasTMFlag(newX, newY, TM_IS_SECRET) + && (!rogue.armor || !(rogue.armor->flags & ITEM_RUNIC) || !(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED) || rogue.armor->enchant2 != A_RESPIRATION + || (!cellHasTerrainType(newX, newY, GAS_TRAP_POISON) && !cellHasTerrainType(newX, newY, GAS_TRAP_PARALYSIS) && !cellHasTerrainType(newX, newY, GAS_TRAP_CONFUSION))) && !confirm("Step onto the pressure plate?", false)) { brogueAssert(!committed); @@ -1023,15 +914,11 @@ boolean playerMoves(short direction) { } if (rogue.weapon && (rogue.weapon->flags & ITEM_LUNGE_ATTACKS)) { - newestX = player.loc.x + 2*nbDirs[direction][0]; - newestY = player.loc.y + 2*nbDirs[direction][1]; + newestX = player.loc.x + 2 * nbDirs[direction][0]; + newestY = player.loc.y + 2 * nbDirs[direction][1]; if (coordinatesAreInMap(newestX, newestY) && (pmap[newestX][newestY].flags & HAS_MONSTER)) { - tempMonst = monsterAtLoc((pos){ newestX, newestY }); - if (tempMonst - && canSeeMonster(tempMonst) - && monstersAreEnemies(&player, tempMonst) - && tempMonst->creatureState != MONSTER_ALLY - && !(tempMonst->bookkeepingFlags & MB_IS_DYING) + tempMonst = monsterAtLoc((pos){newestX, newestY}); + if (tempMonst && canSeeMonster(tempMonst) && monstersAreEnemies(&player, tempMonst) && tempMonst->creatureState != MONSTER_ALLY && !(tempMonst->bookkeepingFlags & MB_IS_DYING) && (!cellHasTerrainFlag(tempMonst->loc.x, tempMonst->loc.y, T_OBSTRUCTS_PASSABILITY) || (tempMonst->info.flags & MONST_ATTACKABLE_THRU_WALLS))) { hitList[0] = tempMonst; @@ -1055,7 +942,7 @@ boolean playerMoves(short direction) { } if (player.status[STATUS_STUCK] && cellHasTerrainFlag(x, y, T_ENTANGLES)) { - // Don't interrupt exploration with this message. + // Don't interrupt exploration with this message. if (--player.status[STATUS_STUCK]) { if (!rogue.automationActive) { message("you struggle but cannot free yourself.", 0); @@ -1106,9 +993,10 @@ boolean playerMoves(short direction) { if (monsterAvoids(defender, (pos){x, y})) { getQualifyingPathLocNear(&(defender->loc.x), &(defender->loc.y), player.loc.x, player.loc.y, true, forbiddenFlagsForMonster(&(defender->info)), 0, 0, (HAS_PLAYER | HAS_MONSTER | HAS_STAIRS), false); } - //getQualifyingLocNear(loc, player.loc.x, player.loc.y, true, NULL, forbiddenFlagsForMonster(&(defender->info)) & ~(T_IS_DF_TRAP | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES), HAS_MONSTER, false, false); - //defender->loc.x = loc[0]; - //defender->loc.y = loc[1]; + // getQualifyingLocNear(loc, player.loc.x, player.loc.y, true, NULL, + // forbiddenFlagsForMonster(&(defender->info)) & ~(T_IS_DF_TRAP | T_IS_DEEP_WATER | + // T_SPONTANEOUSLY_IGNITES), HAS_MONSTER, false, false); defender->loc.x = loc[0]; defender->loc.y = + // loc[1]; pmapAt(defender->loc)->flags |= HAS_MONSTER; } @@ -1127,7 +1015,7 @@ boolean playerMoves(short direction) { moveEntrancedMonsters(direction); // Perform a lunge or flail attack if appropriate. - for (i=0; i<16; i++) { + for (i = 0; i < 16; i++) { if (hitList[i]) { if (attack(&player, hitList[i], (rogue.weapon && (rogue.weapon->flags & ITEM_LUNGE_ATTACKS)))) { anyAttackHit = true; @@ -1142,8 +1030,7 @@ boolean playerMoves(short direction) { } } else if (cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_PASSABILITY)) { i = pmap[newX][newY].layers[layerWithFlag(newX, newY, T_OBSTRUCTS_PASSABILITY)]; - if ((tileCatalog[i].flags & T_OBSTRUCTS_PASSABILITY) - && (!diagonalBlocked(x, y, newX, newY, false) || !cellHasTMFlag(newX, newY, TM_PROMOTES_WITH_KEY))) { + if ((tileCatalog[i].flags & T_OBSTRUCTS_PASSABILITY) && (!diagonalBlocked(x, y, newX, newY, false) || !cellHasTMFlag(newX, newY, TM_PROMOTES_WITH_KEY))) { if (!(pmap[newX][newY].flags & DISCOVERED)) { committed = true; @@ -1359,9 +1246,8 @@ void dijkstraScan(short **distanceMap, char passMap[DCOLS][DROWS], boolean allow }*/ /* -void calculateDistances(short **distanceMap, short destinationX, short destinationY, unsigned long blockingTerrainFlags, creature *traveler) { - short i, j; - boolean somethingChanged; +void calculateDistances(short **distanceMap, short destinationX, short destinationY, unsigned long blockingTerrainFlags, +creature *traveler) { short i, j; boolean somethingChanged; for (i=0; i= 0 : dir < DIRECTION_COUNT); - (preferDiagonals ? dir-- : dir++)) { + for (dir = (preferDiagonals ? 7 : 0); (preferDiagonals ? dir >= 0 : dir < DIRECTION_COUNT); (preferDiagonals ? dir-- : dir++)) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; @@ -1421,22 +1305,14 @@ short nextStep(short **distanceMap, short x, short y, creature *monst, boolean p brogueAssert(coordinatesAreInMap(newX, newY)); if (coordinatesAreInMap(newX, newY)) { blocked = false; - blocker = monsterAtLoc((pos){ newX, newY }); - if (monst - && monsterAvoids(monst, (pos){newX, newY})) { + blocker = monsterAtLoc((pos){newX, newY}); + if (monst && monsterAvoids(monst, (pos){newX, newY})) { blocked = true; - } else if (monst - && blocker - && !canPass(monst, blocker) - && !monstersAreTeammates(monst, blocker) - && !monstersAreEnemies(monst, blocker)) { + } else if (monst && blocker && !canPass(monst, blocker) && !monstersAreTeammates(monst, blocker) && !monstersAreEnemies(monst, blocker)) { blocked = true; } - if ((distanceMap[x][y] - distanceMap[newX][newY]) > bestScore - && !diagonalBlocked(x, y, newX, newY, monst == &player) - && knownToPlayerAsPassableOrSecretDoor(newX, newY) - && !blocked) { + if ((distanceMap[x][y] - distanceMap[newX][newY]) > bestScore && !diagonalBlocked(x, y, newX, newY, monst == &player) && knownToPlayerAsPassableOrSecretDoor(newX, newY) && !blocked) { bestDir = dir; bestScore = distanceMap[x][y] - distanceMap[newX][newY]; @@ -1463,9 +1339,7 @@ void displayRoute(short **distanceMap, boolean removeRoute) { for (dir = 7; dir >= 0; dir--) { newX = currentX + nbDirs[dir][0]; newY = currentY + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && distanceMap[newX][newY] >= 0 && distanceMap[newX][newY] < distanceMap[currentX][currentY] - && !diagonalBlocked(currentX, currentY, newX, newY, true)) { + if (coordinatesAreInMap(newX, newY) && distanceMap[newX][newY] >= 0 && distanceMap[newX][newY] < distanceMap[currentX][currentY] && !diagonalBlocked(currentX, currentY, newX, newY, true)) { currentX = newX; currentY = newY; @@ -1494,11 +1368,10 @@ void travelRoute(pos path[1000], short steps) { } } - for (i=0; i < steps && !rogue.disturbed; i++) { + for (i = 0; i < steps && !rogue.disturbed; i++) { for (j = i + 1; j < steps - 1; j++) { // Check to see if the path has become obstructed or avoided since the last time we saw it. - if (diagonalBlocked(path[j-1].x, path[j-1].y, path[j].x, path[j].y, true) - || monsterAvoids(&player, path[j])) { + if (diagonalBlocked(path[j - 1].x, path[j - 1].y, path[j].x, path[j].y, true) || monsterAvoids(&player, path[j])) { rogue.disturbed = true; break; @@ -1536,10 +1409,7 @@ void travelMap(short **distanceMap) { for (dir = 7; dir >= 0; dir--) { newX = currentX + nbDirs[dir][0]; newY = currentY + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && distanceMap[newX][newY] >= 0 - && distanceMap[newX][newY] < distanceMap[currentX][currentY] - && !diagonalBlocked(currentX, currentY, newX, newY, true)) { + if (coordinatesAreInMap(newX, newY) && distanceMap[newX][newY] >= 0 && distanceMap[newX][newY] < distanceMap[currentX][currentY] && !diagonalBlocked(currentX, currentY, newX, newY, true)) { if (!playerMoves(dir)) { rogue.disturbed = true; @@ -1581,7 +1451,7 @@ void travel(short x, short y, boolean autoConfirm) { if (abs(player.loc.x - x) + abs(player.loc.y - y) == 1) { // targeting a cardinal neighbor - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { if (nbDirs[i][0] == (x - player.loc.x) && nbDirs[i][1] == (y - player.loc.y)) { playerMoves(i); break; @@ -1601,7 +1471,7 @@ void travel(short x, short y, boolean autoConfirm) { if (distanceMap[player.loc.x][player.loc.y] < 30000) { if (autoConfirm) { travelMap(distanceMap); - //refreshSideBar(-1, -1, false); + // refreshSideBar(-1, -1, false); } else { if (rogue.upLoc.x == x && rogue.upLoc.y == y) { staircaseConfirmKey = ASCEND_KEY; @@ -1621,23 +1491,20 @@ void travel(short x, short y, boolean autoConfirm) { confirmMessages(); if ((theEvent.eventType == MOUSE_UP && windowToMapX(theEvent.param1) == x && windowToMapY(theEvent.param2) == y) - || (theEvent.eventType == KEYSTROKE && (theEvent.param1 == 'Y' || theEvent.param1 == 'y' - || theEvent.param1 == RETURN_KEY - || (theEvent.param1 == staircaseConfirmKey - && theEvent.param1 != 0)))) { + || (theEvent.eventType == KEYSTROKE && (theEvent.param1 == 'Y' || theEvent.param1 == 'y' || theEvent.param1 == RETURN_KEY || (theEvent.param1 == staircaseConfirmKey && theEvent.param1 != 0)))) { travelMap(distanceMap); - //refreshSideBar(-1, -1, false); + // refreshSideBar(-1, -1, false); commitDraws(); } else if (theEvent.eventType == MOUSE_UP) { executeMouseClick(&theEvent); } } -// if (player.loc.x == x && player.loc.y == y) { -// rogue.cursorLoc.x = rogue.cursorLoc.y = 0; -// } else { -// rogue.cursorLoc.x = x; -// rogue.cursorLoc.y = y; -// } + // if (player.loc.x == x && player.loc.y == y) { + // rogue.cursorLoc.x = rogue.cursorLoc.y = 0; + // } else { + // rogue.cursorLoc.x = x; + // rogue.cursorLoc.y = y; + // } } else { rogue.cursorLoc = INVALID_POS; message("No path is available.", 0); @@ -1648,10 +1515,9 @@ void travel(short x, short y, boolean autoConfirm) { void populateGenericCostMap(short **costMap) { short i, j; - for (i=0; iinfo.flags & (MONST_IMMUNE_TO_FIRE | MONST_FLIES | MONST_INVULNERABLE)) - && (monst->status[STATUS_LEVITATING] || monst->status[STATUS_IMMUNE_TO_FIRE]) + if ((tFlags & T_LAVA_INSTA_DEATH) && !(monst->info.flags & (MONST_IMMUNE_TO_FIRE | MONST_FLIES | MONST_INVULNERABLE)) && (monst->status[STATUS_LEVITATING] || monst->status[STATUS_IMMUNE_TO_FIRE]) && max(monst->status[STATUS_LEVITATING], monst->status[STATUS_IMMUNE_TO_FIRE]) < (rogue.mapToShore[i][j] + distanceBetween((pos){i, j}, monst->loc) * monst->movementSpeed / 100)) { - // Only a temporary effect will permit the monster to survive the lava, and the remaining duration either isn't - // enough to get it to the spot, or it won't suffice to let it return to shore if it does get there. - // Treat these locations as obstacles. + // Only a temporary effect will permit the monster to survive the lava, and the remaining duration + // either isn't enough to get it to the spot, or it won't suffice to let it return to shore if it does + // get there. Treat these locations as obstacles. costMap[i][j] = PDS_FORBIDDEN; continue; } - if (((tFlags & T_AUTO_DESCENT) || (tFlags & T_IS_DEEP_WATER) && !(monst->info.flags & MONST_IMMUNE_TO_WATER)) - && !(monst->info.flags & MONST_FLIES) - && (monst->status[STATUS_LEVITATING]) + if (((tFlags & T_AUTO_DESCENT) || (tFlags & T_IS_DEEP_WATER) && !(monst->info.flags & MONST_IMMUNE_TO_WATER)) && !(monst->info.flags & MONST_FLIES) && (monst->status[STATUS_LEVITATING]) && monst->status[STATUS_LEVITATING] < (rogue.mapToShore[i][j] + distanceBetween((pos){i, j}, monst->loc) * monst->movementSpeed / 100)) { - // Only a temporary effect will permit the monster to levitate over the chasm/water, and the remaining duration either isn't - // enough to get it to the spot, or it won't suffice to let it return to shore if it does get there. - // Treat these locations as obstacles. + // Only a temporary effect will permit the monster to levitate over the chasm/water, and the remaining + // duration either isn't enough to get it to the spot, or it won't suffice to let it return to shore if + // it does get there. Treat these locations as obstacles. costMap[i][j] = PDS_FORBIDDEN; continue; } @@ -1744,18 +1601,15 @@ void populateCreatureCostMap(short **costMap, creature *monst) { } if (cFlags & HAS_MONSTER) { - currentTenant = monsterAtLoc((pos){ i, j }); - if (currentTenant - && (currentTenant->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) - && !canPass(monst, currentTenant)) { + currentTenant = monsterAtLoc((pos){i, j}); + if (currentTenant && (currentTenant->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) && !canPass(monst, currentTenant)) { costMap[i][j] = PDS_FORBIDDEN; continue; } } - if ((cFlags & KNOWN_TO_BE_TRAP_FREE) - || (monst != &player && monst->creatureState != MONSTER_ALLY)) { + if ((cFlags & KNOWN_TO_BE_TRAP_FREE) || (monst != &player && monst->creatureState != MONSTER_ALLY)) { costMap[i][j] = 10; } else { @@ -1766,9 +1620,7 @@ void populateCreatureCostMap(short **costMap, creature *monst) { } if (!(monst->info.flags & MONST_INVULNERABLE)) { - if ((tFlags & T_CAUSES_NAUSEA) - || cellHasTMFlag(i, j, TM_PROMOTES_ON_ITEM_PICKUP) - || (tFlags & T_ENTANGLES) && !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) { + if ((tFlags & T_CAUSES_NAUSEA) || cellHasTMFlag(i, j, TM_PROMOTES_ON_ITEM_PICKUP) || (tFlags & T_ENTANGLES) && !(monst->info.flags & MONST_IMMUNE_TO_WEBS)) { costMap[i][j] += 20; } @@ -1791,10 +1643,7 @@ enum directions adjacentFightingDir() { for (enum directions dir = 0; dir < DIRECTION_COUNT; dir++) { const pos newLoc = posNeighborInDirection(player.loc, dir); creature *const monst = monsterAtLoc(newLoc); - if (monst - && canSeeMonster(monst) - && (!diagonalBlocked(player.loc.x, player.loc.y, newLoc.x, newLoc.y, false) || (monst->info.flags & MONST_ATTACKABLE_THRU_WALLS)) - && monstersAreEnemies(&player, monst) + if (monst && canSeeMonster(monst) && (!diagonalBlocked(player.loc.x, player.loc.y, newLoc.x, newLoc.y, false) || (monst->info.flags & MONST_ATTACKABLE_THRU_WALLS)) && monstersAreEnemies(&player, monst) && !(monst->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE))) { return dir; @@ -1803,9 +1652,9 @@ enum directions adjacentFightingDir() { return NO_DIRECTION; } -#define exploreGoalValue(x, y) (0 - abs((x) - DCOLS / 2) / 3 - abs((x) - DCOLS / 2) / 4) +#define exploreGoalValue(x, y) (0 - abs((x)-DCOLS / 2) / 3 - abs((x)-DCOLS / 2) / 4) -void getExploreMap(short **map, boolean headingToStairs) {// calculate explore map +void getExploreMap(short **map, boolean headingToStairs) { // calculate explore map short i, j; short **costMap; item *theItem; @@ -1813,21 +1662,20 @@ void getExploreMap(short **map, boolean headingToStairs) {// calculate explore m costMap = allocGrid(); populateCreatureCostMap(costMap, &player); - for (i=0; iflags & ITEM_PLAYER_AVOIDS) { costMap[i][j] = 20; } else { @@ -1839,7 +1687,7 @@ void getExploreMap(short **map, boolean headingToStairs) {// calculate explore m } costMap[rogue.downLoc.x][rogue.downLoc.y] = 100; - costMap[rogue.upLoc.x][rogue.upLoc.y] = 100; + costMap[rogue.upLoc.x][rogue.upLoc.y] = 100; if (headingToStairs) { map[rogue.downLoc.x][rogue.downLoc.y] = 0; // head to the stairs @@ -1847,7 +1695,7 @@ void getExploreMap(short **map, boolean headingToStairs) {// calculate explore m dijkstraScan(map, costMap, true); - //displayGrid(costMap); + // displayGrid(costMap); freeGrid(costMap); } @@ -1859,7 +1707,7 @@ boolean explore(short frameDelay) { clearCursorPath(); - boolean madeProgress = false; + boolean madeProgress = false; boolean headingToStairs = false; if (player.status[STATUS_CONFUSED]) { @@ -1882,25 +1730,22 @@ boolean explore(short frameDelay) { // fight any adjacent enemies enum directions dir = adjacentFightingDir(); - if (dir != NO_DIRECTION - && startFighting(dir, (player.status[STATUS_HALLUCINATING] ? true : false))) { + if (dir != NO_DIRECTION && startFighting(dir, (player.status[STATUS_HALLUCINATING] ? true : false))) { return true; } if (!rogue.autoPlayingLevel) { - message(KEYBOARD_LABELS ? "Exploring... press any key to stop." : "Exploring... touch anywhere to stop.", - 0); + message(KEYBOARD_LABELS ? "Exploring... press any key to stop." : "Exploring... touch anywhere to stop.", 0); // A little hack so the exploring message remains bright while exploring and then auto-dims when // another message is displayed: confirmMessages(); - printString(KEYBOARD_LABELS ? "Exploring... press any key to stop." : "Exploring... touch anywhere to stop.", - mapToWindowX(0), mapToWindowY(-1), &white, &black, NULL); + printString(KEYBOARD_LABELS ? "Exploring... press any key to stop." : "Exploring... touch anywhere to stop.", mapToWindowX(0), mapToWindowY(-1), &white, &black, NULL); } rogue.disturbed = false; rogue.automationActive = true; - short** distanceMap = allocGrid(); + short **distanceMap = allocGrid(); do { // fight any adjacent enemies dir = adjacentFightingDir(); @@ -1945,7 +1790,7 @@ boolean explore(short frameDelay) { } hilitePath(path, steps, true); } while (!rogue.disturbed); - //clearCursorPath(); + // clearCursorPath(); rogue.automationActive = false; refreshSideBar(-1, -1, false); freeGrid(distanceMap); @@ -1963,7 +1808,7 @@ void autoPlayLevel(boolean fastForward) { // explore until we are not making progress do { madeProgress = explore(fastForward ? 1 : 50); - //refreshSideBar(-1, -1, false); + // refreshSideBar(-1, -1, false); if (!madeProgress && rogue.downLoc.x == player.loc.x && rogue.downLoc.y == player.loc.y) { useStairs(1); @@ -2013,7 +1858,7 @@ short directionOfKeypress(unsigned short ch) { boolean startFighting(enum directions dir, boolean tillDeath) { const pos neighborLoc = posNeighborInDirection(player.loc, dir); - creature * const monst = monsterAtLoc(neighborLoc); + creature *const monst = monsterAtLoc(neighborLoc); if (monst->info.flags & (MONST_IMMUNE_TO_WEAPONS | MONST_INVULNERABLE)) { return false; } @@ -2030,25 +1875,22 @@ boolean startFighting(enum directions dir, boolean tillDeath) { if (pauseAnimation(1)) { break; } - } while (!rogue.disturbed && !rogue.gameHasEnded && (tillDeath || player.currentHP > expectedDamage) - && (pmapAt(neighborLoc)->flags & HAS_MONSTER) && monsterAtLoc(neighborLoc) == monst); + } while (!rogue.disturbed && !rogue.gameHasEnded && (tillDeath || player.currentHP > expectedDamage) && (pmapAt(neighborLoc)->flags & HAS_MONSTER) && monsterAtLoc(neighborLoc) == monst); rogue.blockCombatText = false; return rogue.disturbed; } boolean isDisturbed(short x, short y) { - pos p = (pos){ x, y }; - for (int i=0; i< DIRECTION_COUNT; i++) { + pos p = (pos){x, y}; + for (int i = 0; i < DIRECTION_COUNT; i++) { const pos neighborPos = posNeighborInDirection(p, i); creature *const monst = monsterAtLoc(neighborPos); if (pmapAt(neighborPos)->flags & (HAS_ITEM)) { // Do not trigger for submerged or invisible or unseen monsters. return true; } - if (monst - && !(monst->creatureState == MONSTER_ALLY) - && (canSeeMonster(monst) || monsterRevealed(monst))) { + if (monst && !(monst->creatureState == MONSTER_ALLY) && (canSeeMonster(monst) || monsterRevealed(monst))) { // Do not trigger for submerged or invisible or unseen monsters. return true; } @@ -2087,12 +1929,11 @@ boolean search(short searchStrength) { for (i = x - radius; i <= x + radius; i++) { for (j = y - radius; j <= y + radius; j++) { - if (coordinatesAreInMap(i, j) - && playerCanDirectlySee(i, j)) { + if (coordinatesAreInMap(i, j) && playerCanDirectlySee(i, j)) { percent = searchStrength - distanceBetween((pos){x, y}, (pos){i, j}) * 10; if (cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY)) { - percent = percent * 2/3; + percent = percent * 2 / 3; } if (percent >= 100) { pmap[i][j].flags |= KNOWN_TO_BE_TRAP_FREE; @@ -2129,11 +1970,11 @@ boolean proposeOrConfirmLocation(short x, short y, char *failureMessage) { boolean useStairs(short stairDirection) { boolean succeeded = false; - //cellDisplayBuffer fromBuf[COLS][ROWS], toBuf[COLS][ROWS]; + // cellDisplayBuffer fromBuf[COLS][ROWS], toBuf[COLS][ROWS]; if (stairDirection == 1) { if (rogue.depthLevel < gameConst->deepestLevel) { - //copyDisplayBuffer(fromBuf, displayBuffer); + // copyDisplayBuffer(fromBuf, displayBuffer); rogue.cursorLoc = INVALID_POS; rogue.depthLevel++; message("You descend.", 0); @@ -2141,8 +1982,9 @@ boolean useStairs(short stairDirection) { if (rogue.depthLevel > rogue.deepestLevel) { rogue.deepestLevel = rogue.depthLevel; } - //copyDisplayBuffer(toBuf, displayBuffer); - //irisFadeBetweenBuffers(fromBuf, toBuf, mapToWindowX(player.loc.x), mapToWindowY(player.loc.y), 20, false); + // copyDisplayBuffer(toBuf, displayBuffer); + // irisFadeBetweenBuffers(fromBuf, toBuf, mapToWindowX(player.loc.x), mapToWindowY(player.loc.y), 20, + // false); } else if (numberOfMatchingPackItems(AMULET, 0, 0, false)) { victory(true); } else { @@ -2158,11 +2000,12 @@ boolean useStairs(short stairDirection) { if (rogue.depthLevel == 0) { victory(false); } else { - //copyDisplayBuffer(fromBuf, displayBuffer); + // copyDisplayBuffer(fromBuf, displayBuffer); message("You ascend.", 0); startLevel(rogue.depthLevel + 1, stairDirection); - //copyDisplayBuffer(toBuf, displayBuffer); - //irisFadeBetweenBuffers(fromBuf, toBuf, mapToWindowX(player.loc.x), mapToWindowY(player.loc.y), 20, true); + // copyDisplayBuffer(toBuf, displayBuffer); + // irisFadeBetweenBuffers(fromBuf, toBuf, mapToWindowX(player.loc.x), mapToWindowY(player.loc.y), 20, + // true); } succeeded = true; } else { @@ -2189,17 +2032,13 @@ void storeMemories(const short x, const short y) { void updateFieldOfViewDisplay(boolean updateDancingTerrain, boolean refreshDisplay) { short i, j; item *theItem; - char buf[COLS*3], name[COLS*3]; + char buf[COLS * 3], name[COLS * 3]; assureCosmeticRNG; - for (i=0; i= 0; j--) { - if (pmap[i][j].flags & IN_FIELD_OF_VIEW - && (max(0, tmap[i][j].light[0]) - + max(0, tmap[i][j].light[1]) - + max(0, tmap[i][j].light[2]) > VISIBILITY_THRESHOLD) - && !(pmap[i][j].flags & CLAIRVOYANT_DARKENED)) { + for (i = 0; i < DCOLS; i++) { + for (j = DROWS - 1; j >= 0; j--) { + if (pmap[i][j].flags & IN_FIELD_OF_VIEW && (max(0, tmap[i][j].light[0]) + max(0, tmap[i][j].light[1]) + max(0, tmap[i][j].light[2]) > VISIBILITY_THRESHOLD) && !(pmap[i][j].flags & CLAIRVOYANT_DARKENED)) { pmap[i][j].flags |= VISIBLE; } @@ -2214,8 +2053,7 @@ void updateFieldOfViewDisplay(boolean updateDancingTerrain, boolean refreshDispl messageWithColor(buf, &itemMessageColor, 0); } } - if (!(pmap[i][j].flags & MAGIC_MAPPED) - && cellHasTMFlag(i, j, TM_INTERRUPT_EXPLORATION_WHEN_SEEN)) { + if (!(pmap[i][j].flags & MAGIC_MAPPED) && cellHasTMFlag(i, j, TM_INTERRUPT_EXPLORATION_WHEN_SEEN)) { strcpy(name, tileCatalog[pmap[i][j].layers[layerWithTMFlag(i, j, TM_INTERRUPT_EXPLORATION_WHEN_SEEN)]].description); sprintf(buf, "you see %s.", name); @@ -2247,8 +2085,7 @@ void updateFieldOfViewDisplay(boolean updateDancingTerrain, boolean refreshDispl refreshDungeonCell(i, j); } } else if (!(pmap[i][j].flags & WAS_TELEPATHIC_VISIBLE) && (pmap[i][j].flags & TELEPATHIC_VISIBLE)) { // became telepathically visible - if (!(pmap[i][j].flags & DISCOVERED) - && !cellHasTerrainFlag(i, j, T_PATHING_BLOCKER)) { + if (!(pmap[i][j].flags & DISCOVERED) && !cellHasTerrainFlag(i, j, T_PATHING_BLOCKER)) { rogue.xpxpThisTurn++; } @@ -2257,31 +2094,26 @@ void updateFieldOfViewDisplay(boolean updateDancingTerrain, boolean refreshDispl refreshDungeonCell(i, j); } } else if (playerCanSeeOrSense(i, j) - && (tmap[i][j].light[0] != tmap[i][j].oldLight[0] || - tmap[i][j].light[1] != tmap[i][j].oldLight[1] || - tmap[i][j].light[2] != tmap[i][j].oldLight[2])) { // if the cell's light color changed this move - - if (refreshDisplay) { - refreshDungeonCell(i, j); - } - } else if (updateDancingTerrain - && playerCanSee(i, j) - && (!rogue.automationActive || !(rogue.playerTurnNumber % 5)) - && ((tileCatalog[pmap[i][j].layers[DUNGEON]].backColor) && tileCatalog[pmap[i][j].layers[DUNGEON]].backColor->colorDances - || (tileCatalog[pmap[i][j].layers[DUNGEON]].foreColor) && tileCatalog[pmap[i][j].layers[DUNGEON]].foreColor->colorDances - || (tileCatalog[pmap[i][j].layers[LIQUID]].backColor) && tileCatalog[pmap[i][j].layers[LIQUID]].backColor->colorDances - || (tileCatalog[pmap[i][j].layers[LIQUID]].foreColor) && tileCatalog[pmap[i][j].layers[LIQUID]].foreColor->colorDances - || (tileCatalog[pmap[i][j].layers[SURFACE]].backColor) && tileCatalog[pmap[i][j].layers[SURFACE]].backColor->colorDances - || (tileCatalog[pmap[i][j].layers[SURFACE]].foreColor) && tileCatalog[pmap[i][j].layers[SURFACE]].foreColor->colorDances - || (tileCatalog[pmap[i][j].layers[GAS]].backColor) && tileCatalog[pmap[i][j].layers[GAS]].backColor->colorDances - || (tileCatalog[pmap[i][j].layers[GAS]].foreColor) && tileCatalog[pmap[i][j].layers[GAS]].foreColor->colorDances - || player.status[STATUS_HALLUCINATING])) { - - pmap[i][j].flags &= ~STABLE_MEMORY; - if (refreshDisplay) { - refreshDungeonCell(i, j); - } - } + && (tmap[i][j].light[0] != tmap[i][j].oldLight[0] || tmap[i][j].light[1] != tmap[i][j].oldLight[1] || tmap[i][j].light[2] != tmap[i][j].oldLight[2])) { // if the cell's light color changed this move + + if (refreshDisplay) { + refreshDungeonCell(i, j); + } + } else if (updateDancingTerrain && playerCanSee(i, j) && (!rogue.automationActive || !(rogue.playerTurnNumber % 5)) + && ((tileCatalog[pmap[i][j].layers[DUNGEON]].backColor) && tileCatalog[pmap[i][j].layers[DUNGEON]].backColor->colorDances + || (tileCatalog[pmap[i][j].layers[DUNGEON]].foreColor) && tileCatalog[pmap[i][j].layers[DUNGEON]].foreColor->colorDances + || (tileCatalog[pmap[i][j].layers[LIQUID]].backColor) && tileCatalog[pmap[i][j].layers[LIQUID]].backColor->colorDances + || (tileCatalog[pmap[i][j].layers[LIQUID]].foreColor) && tileCatalog[pmap[i][j].layers[LIQUID]].foreColor->colorDances + || (tileCatalog[pmap[i][j].layers[SURFACE]].backColor) && tileCatalog[pmap[i][j].layers[SURFACE]].backColor->colorDances + || (tileCatalog[pmap[i][j].layers[SURFACE]].foreColor) && tileCatalog[pmap[i][j].layers[SURFACE]].foreColor->colorDances + || (tileCatalog[pmap[i][j].layers[GAS]].backColor) && tileCatalog[pmap[i][j].layers[GAS]].backColor->colorDances + || (tileCatalog[pmap[i][j].layers[GAS]].foreColor) && tileCatalog[pmap[i][j].layers[GAS]].foreColor->colorDances || player.status[STATUS_HALLUCINATING])) { + + pmap[i][j].flags &= ~STABLE_MEMORY; + if (refreshDisplay) { + refreshDungeonCell(i, j); + } + } } } restoreRNG; @@ -2335,21 +2167,18 @@ void betweenOctant1andN(short *x, short *y, short x0, short y0, short n) { // If cautiousOnWalls is set, we will not illuminate blocking tiles unless the tile one space closer to the origin // is visible to the player; this is to prevent lights from illuminating a wall when the player is on the other // side of the wall. -void getFOVMask(char grid[DCOLS][DROWS], short xLoc, short yLoc, fixpt maxRadius, - unsigned long forbiddenTerrain, unsigned long forbiddenFlags, boolean cautiousOnWalls) { - pos loc = { xLoc, yLoc }; +void getFOVMask(char grid[DCOLS][DROWS], short xLoc, short yLoc, fixpt maxRadius, unsigned long forbiddenTerrain, unsigned long forbiddenFlags, boolean cautiousOnWalls) { + pos loc = {xLoc, yLoc}; - for (int i=1; i<=8; i++) { - scanOctantFOV(grid, loc.x, loc.y, i, maxRadius, 1, LOS_SLOPE_GRANULARITY * -1, 0, - forbiddenTerrain, forbiddenFlags, cautiousOnWalls); + for (int i = 1; i <= 8; i++) { + scanOctantFOV(grid, loc.x, loc.y, i, maxRadius, 1, LOS_SLOPE_GRANULARITY * -1, 0, forbiddenTerrain, forbiddenFlags, cautiousOnWalls); } } // This is a custom implementation of recursive shadowcasting. -void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant, fixpt maxRadius, - short columnsRightFromOrigin, long startSlope, long endSlope, unsigned long forbiddenTerrain, - unsigned long forbiddenFlags, boolean cautiousOnWalls) { - const pos loc = { xLoc, yLoc }; +void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant, fixpt maxRadius, short columnsRightFromOrigin, long startSlope, long endSlope, unsigned long forbiddenTerrain, unsigned long forbiddenFlags, + boolean cautiousOnWalls) { + const pos loc = {xLoc, yLoc}; if (columnsRightFromOrigin * FP_FACTOR >= maxRadius) return; @@ -2366,18 +2195,17 @@ void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant iEnd = max(a, b); // restrict vision to a circle of radius maxRadius - if ((columnsRightFromOrigin*columnsRightFromOrigin + iEnd*iEnd) >= maxRadius*maxRadius / FP_FACTOR / FP_FACTOR) { + if ((columnsRightFromOrigin * columnsRightFromOrigin + iEnd * iEnd) >= maxRadius * maxRadius / FP_FACTOR / FP_FACTOR) { return; } - if ((columnsRightFromOrigin*columnsRightFromOrigin + iStart*iStart) >= maxRadius*maxRadius / FP_FACTOR / FP_FACTOR) { - iStart = (int) (-1 * fp_sqrt((maxRadius*maxRadius / FP_FACTOR) - (columnsRightFromOrigin*columnsRightFromOrigin * FP_FACTOR)) / FP_FACTOR); + if ((columnsRightFromOrigin * columnsRightFromOrigin + iStart * iStart) >= maxRadius * maxRadius / FP_FACTOR / FP_FACTOR) { + iStart = (int)(-1 * fp_sqrt((maxRadius * maxRadius / FP_FACTOR) - (columnsRightFromOrigin * columnsRightFromOrigin * FP_FACTOR)) / FP_FACTOR); } x = loc.x + columnsRightFromOrigin; y = loc.y + iStart; betweenOctant1andN(&x, &y, loc.x, loc.y, octant); - boolean currentlyLit = coordinatesAreInMap(x, y) && !(cellHasTerrainFlag(x, y, forbiddenTerrain) || - (pmap[x][y].flags & forbiddenFlags)); + boolean currentlyLit = coordinatesAreInMap(x, y) && !(cellHasTerrainFlag(x, y, forbiddenTerrain) || (pmap[x][y].flags & forbiddenFlags)); for (i = iStart; i <= iEnd; i++) { x = loc.x + columnsRightFromOrigin; y = loc.y + i; @@ -2408,15 +2236,13 @@ void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant grid[x][y] = 1; } if (!cellObstructed && !currentlyLit) { // next column slope starts here - newStartSlope = (long int) ((LOS_SLOPE_GRANULARITY * (i) - LOS_SLOPE_GRANULARITY / 2) / (columnsRightFromOrigin * 2 + 1) * 2); + newStartSlope = (long int)((LOS_SLOPE_GRANULARITY * (i)-LOS_SLOPE_GRANULARITY / 2) / (columnsRightFromOrigin * 2 + 1) * 2); currentlyLit = true; } else if (cellObstructed && currentlyLit) { // next column slope ends here - newEndSlope = (long int) ((LOS_SLOPE_GRANULARITY * (i) - LOS_SLOPE_GRANULARITY / 2) - / (columnsRightFromOrigin * 2 - 1) * 2); + newEndSlope = (long int)((LOS_SLOPE_GRANULARITY * (i)-LOS_SLOPE_GRANULARITY / 2) / (columnsRightFromOrigin * 2 - 1) * 2); if (newStartSlope <= newEndSlope) { // run next column - scanOctantFOV(grid, loc.x, loc.y, octant, maxRadius, columnsRightFromOrigin + 1, newStartSlope, newEndSlope, - forbiddenTerrain, forbiddenFlags, cautiousOnWalls); + scanOctantFOV(grid, loc.x, loc.y, octant, maxRadius, columnsRightFromOrigin + 1, newStartSlope, newEndSlope, forbiddenTerrain, forbiddenFlags, cautiousOnWalls); } currentlyLit = false; } @@ -2425,8 +2251,7 @@ void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant newEndSlope = endSlope; if (newStartSlope <= newEndSlope) { // run next column - scanOctantFOV(grid, loc.x, loc.y, octant, maxRadius, columnsRightFromOrigin + 1, newStartSlope, newEndSlope, - forbiddenTerrain, forbiddenFlags, cautiousOnWalls); + scanOctantFOV(grid, loc.x, loc.y, octant, maxRadius, columnsRightFromOrigin + 1, newStartSlope, newEndSlope, forbiddenTerrain, forbiddenFlags, cautiousOnWalls); } } } @@ -2435,6 +2260,6 @@ void addScentToCell(short x, short y, short distance) { unsigned short value; if (!cellHasTerrainFlag(x, y, T_OBSTRUCTS_SCENT) || !cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) { value = rogue.scentTurnNumber - distance; - scentMap[x][y] = max(value, (unsigned short) scentMap[x][y]); + scentMap[x][y] = max(value, (unsigned short)scentMap[x][y]); } } diff --git a/src/brogue/PowerTables.c b/src/brogue/PowerTables.c index 3d0ae989..24f56240 100644 --- a/src/brogue/PowerTables.c +++ b/src/brogue/PowerTables.c @@ -42,91 +42,80 @@ // game data formulae: -short wandDominate(creature *monst) {return (((monst)->currentHP * 5 < (monst)->info.maxHP) ? 100 : \ - max(0, 100 * ((monst)->info.maxHP - (monst)->currentHP) / (monst)->info.maxHP));} +short wandDominate(creature *monst) { return (((monst)->currentHP * 5 < (monst)->info.maxHP) ? 100 : max(0, 100 * ((monst)->info.maxHP - (monst)->currentHP) / (monst)->info.maxHP)); } // All "enchant" parameters must already be multiplied by FP_FACTOR: -short staffDamageLow(fixpt enchant) {return ((int) ((2 + enchant / FP_FACTOR) * 3 / 4));} -short staffDamageHigh(fixpt enchant) {return ((int) (4 + (5 * enchant / FP_FACTOR / 2)));} -short staffDamage(fixpt enchant) {return ((int) randClumpedRange(staffDamageLow(enchant), staffDamageHigh(enchant), 1 + (enchant) / 3 / FP_FACTOR));} -short staffBlinkDistance(fixpt enchant) {return ((int) (2 + enchant * 2 / FP_FACTOR));} -short staffHasteDuration(fixpt enchant) {return ((int) (2 + enchant * 4 / FP_FACTOR));} -short staffBladeCount(fixpt enchant) {return ((int) (enchant * 3 / 2 / FP_FACTOR));} -short staffDiscordDuration(fixpt enchant) {return ((int) (enchant * 4 / FP_FACTOR));} -short staffEntrancementDuration(fixpt enchant) {return ((int) (enchant * 3 / FP_FACTOR));} -int staffProtection(fixpt enchant) { - return 130 * fp_pow(FP_FACTOR * 140 / 100, enchant / FP_FACTOR - 2) / FP_FACTOR; -} +short staffDamageLow(fixpt enchant) { return ((int)((2 + enchant / FP_FACTOR) * 3 / 4)); } +short staffDamageHigh(fixpt enchant) { return ((int)(4 + (5 * enchant / FP_FACTOR / 2))); } +short staffDamage(fixpt enchant) { return ((int)randClumpedRange(staffDamageLow(enchant), staffDamageHigh(enchant), 1 + (enchant) / 3 / FP_FACTOR)); } +short staffBlinkDistance(fixpt enchant) { return ((int)(2 + enchant * 2 / FP_FACTOR)); } +short staffHasteDuration(fixpt enchant) { return ((int)(2 + enchant * 4 / FP_FACTOR)); } +short staffBladeCount(fixpt enchant) { return ((int)(enchant * 3 / 2 / FP_FACTOR)); } +short staffDiscordDuration(fixpt enchant) { return ((int)(enchant * 4 / FP_FACTOR)); } +short staffEntrancementDuration(fixpt enchant) { return ((int)(enchant * 3 / FP_FACTOR)); } +int staffProtection(fixpt enchant) { return 130 * fp_pow(FP_FACTOR * 140 / 100, enchant / FP_FACTOR - 2) / FP_FACTOR; } int staffPoison(fixpt enchant) { - const fixpt POW_POISON[] = { - // 1.3^x fixed point, with x from 0 to 50 in increments of 1: - 65536, 85196, 110755, 143982, 187177, 243330, 316329, 411228, 534597, 694976, 903469, 1174510, 1526863, 1984922, 2580398, 3354518, 4360874, 5669136, 7369877, - 9580840, 12455093, 16191620, 21049107, 27363839, 35572991, 46244888, 60118355, 78153861, 101600020, 132080026, 171704034, 223215244, 290179818, 377233763, - 490403892, 637525060, 828782579, 1077417352, 1400642558, 1820835326, 2367085924, 3077211701, 4000375211, 5200487775, 6760634107, 8788824340, 11425471642, - 14853113134, 19309047075, 25101761197, 32632289557}; + const fixpt POW_POISON[] = {// 1.3^x fixed point, with x from 0 to 50 in increments of 1: + 65536, 85196, 110755, 143982, 187177, 243330, 316329, 411228, 534597, 694976, 903469, 1174510, 1526863, 1984922, 2580398, 3354518, 4360874, + 5669136, 7369877, 9580840, 12455093, 16191620, 21049107, 27363839, 35572991, 46244888, 60118355, 78153861, 101600020, 132080026, 171704034, 223215244, 290179818, 377233763, + 490403892, 637525060, 828782579, 1077417352, 1400642558, 1820835326, 2367085924, 3077211701, 4000375211, 5200487775, 6760634107, 8788824340, 11425471642, 14853113134, 19309047075, 25101761197, 32632289557}; short idx = clamp(enchant / FP_FACTOR - 2, 0, LAST_INDEX(POW_POISON)); return 5 * POW_POISON[idx] / FP_FACTOR; } fixpt ringWisdomMultiplier(fixpt enchant) { - const fixpt POW_WISDOM[] = { - // 1.3^x fixed point, with x from -10 to 30 in increments of 1: - 4753, 6180, 8034, 10444, 13577, 17650, 22945, 29829, 38778, 50412, 65536, 85196, 110755, 143982, 187177, 243330, 316329, 411228, 534597, 694976, 903469, - 1174510, 1526863, 1984922, 2580398, 3354518, 4360874, 5669136, 7369877, 9580840, 12455093, 16191620, 21049107, 27363839, 35572991, 46244888, 60118355, - 78153861, 101600020, 132080026, 171704034}; + const fixpt POW_WISDOM[] = {// 1.3^x fixed point, with x from -10 to 30 in increments of 1: + 4753, 6180, 8034, 10444, 13577, 17650, 22945, 29829, 38778, 50412, 65536, 85196, 110755, 143982, 187177, 243330, 316329, 411228, 534597, 694976, 903469, + 1174510, 1526863, 1984922, 2580398, 3354518, 4360874, 5669136, 7369877, 9580840, 12455093, 16191620, 21049107, 27363839, 35572991, 46244888, 60118355, 78153861, 101600020, 132080026, 171704034}; short idx = clamp(min(27, enchant / FP_FACTOR) + 10, 0, LAST_INDEX(POW_WISDOM)); return POW_WISDOM[idx]; } -short charmHealing(fixpt enchant) {return ((int) clamp(charmEffectTable[CHARM_HEALTH].effectMagnitudeMultiplier * (enchant) / FP_FACTOR, 0, 100));} -short charmShattering(fixpt enchant) {return ((int) (charmEffectTable[CHARM_SHATTERING].effectMagnitudeConstant + (enchant / FP_FACTOR)));} -short charmGuardianLifespan(fixpt enchant) {return ((int) (charmEffectTable[CHARM_GUARDIAN].effectMagnitudeConstant + charmEffectTable[CHARM_GUARDIAN].effectMagnitudeMultiplier * (enchant / FP_FACTOR)));} -short charmNegationRadius(fixpt enchant) {return ((int) (charmEffectTable[CHARM_NEGATION].effectMagnitudeConstant + charmEffectTable[CHARM_NEGATION].effectMagnitudeMultiplier * (enchant / FP_FACTOR)));} +short charmHealing(fixpt enchant) { return ((int)clamp(charmEffectTable[CHARM_HEALTH].effectMagnitudeMultiplier * (enchant) / FP_FACTOR, 0, 100)); } +short charmShattering(fixpt enchant) { return ((int)(charmEffectTable[CHARM_SHATTERING].effectMagnitudeConstant + (enchant / FP_FACTOR))); } +short charmGuardianLifespan(fixpt enchant) { return ((int)(charmEffectTable[CHARM_GUARDIAN].effectMagnitudeConstant + charmEffectTable[CHARM_GUARDIAN].effectMagnitudeMultiplier * (enchant / FP_FACTOR))); } +short charmNegationRadius(fixpt enchant) { return ((int)(charmEffectTable[CHARM_NEGATION].effectMagnitudeConstant + charmEffectTable[CHARM_NEGATION].effectMagnitudeMultiplier * (enchant / FP_FACTOR))); } int charmProtection(fixpt enchant) { - const fixpt POW_CHARM_PROTECTION[] = { - // 1.35^x fixed point, with x from 0 to 50 in increments of 1: - 65536, 88473, 119439, 161243, 217678, 293865, 396718, 535570, 723019, 976076, 1317703, 1778899, 2401514, 3242044, 4376759, 5908625, 7976644, 10768469, - 14537434, 19625536, 26494473, 35767539, 48286178, 65186341, 88001560, 118802106, 160382844, 216516839, 292297733, 394601940, 532712620, 719162037, 970868750, - 1310672812, 1769408297, 2388701201, 3224746621, 4353407939, 5877100717, 7934085969, 10711016058, 14459871678, 19520826766, 26353116134, 35576706781, - 48028554155, 64838548109, 87532039948, 118168253930, 159527142806, 215361642788}; + const fixpt POW_CHARM_PROTECTION[] + = {// 1.35^x fixed point, with x from 0 to 50 in increments of 1: + 65536, 88473, 119439, 161243, 217678, 293865, 396718, 535570, 723019, 976076, 1317703, 1778899, 2401514, 3242044, 4376759, 5908625, 7976644, + 10768469, 14537434, 19625536, 26494473, 35767539, 48286178, 65186341, 88001560, 118802106, 160382844, 216516839, 292297733, 394601940, 532712620, 719162037, 970868750, 1310672812, + 1769408297, 2388701201, 3224746621, 4353407939, 5877100717, 7934085969, 10711016058, 14459871678, 19520826766, 26353116134, 35576706781, 48028554155, 64838548109, 87532039948, 118168253930, 159527142806, 215361642788}; short idx = clamp(enchant / FP_FACTOR - 1, 0, LAST_INDEX(POW_CHARM_PROTECTION)); return charmEffectTable[CHARM_PROTECTION].effectMagnitudeMultiplier * POW_CHARM_PROTECTION[idx] / FP_FACTOR; } -short weaponParalysisDuration(fixpt enchant) {return (max(2, (int) (2 + ((enchant) / 2 / FP_FACTOR))));} -short weaponConfusionDuration(fixpt enchant) {return (max(3, (int) ((enchant) * 3/2 / FP_FACTOR)));} -short weaponForceDistance(fixpt enchant) {return (max(4, (int) (((enchant) * 2 / FP_FACTOR) + 2)));} // Depends on definition of staffBlinkDistance() above. -short weaponSlowDuration(fixpt enchant) {return (max(3, (int) ((((enchant) / FP_FACTOR) + 2) * ((enchant) + (2 * FP_FACTOR))) / 3 / FP_FACTOR));} -short weaponImageCount(fixpt enchant) {return (clamp((int) ((enchant) / 3 / FP_FACTOR), 1, 7));} -short weaponImageDuration(fixpt enchant) {return 3;} +short weaponParalysisDuration(fixpt enchant) { return (max(2, (int)(2 + ((enchant) / 2 / FP_FACTOR)))); } +short weaponConfusionDuration(fixpt enchant) { return (max(3, (int)((enchant)*3 / 2 / FP_FACTOR))); } +short weaponForceDistance(fixpt enchant) { return (max(4, (int)(((enchant)*2 / FP_FACTOR) + 2))); } // Depends on definition of staffBlinkDistance() above. +short weaponSlowDuration(fixpt enchant) { return (max(3, (int)((((enchant) / FP_FACTOR) + 2) * ((enchant) + (2 * FP_FACTOR))) / 3 / FP_FACTOR)); } +short weaponImageCount(fixpt enchant) { return (clamp((int)((enchant) / 3 / FP_FACTOR), 1, 7)); } +short weaponImageDuration(fixpt enchant) { return 3; } -short armorReprisalPercent(fixpt enchant) {return (max(5, (int) ((enchant) * 5 / FP_FACTOR)));} -short armorAbsorptionMax(fixpt enchant) {return (max(1, (int) ((enchant) / FP_FACTOR)));} -short armorImageCount(fixpt enchant) {return (clamp((int) ((enchant) / 3 / FP_FACTOR), 1, 5));} +short armorReprisalPercent(fixpt enchant) { return (max(5, (int)((enchant)*5 / FP_FACTOR))); } +short armorAbsorptionMax(fixpt enchant) { return (max(1, (int)((enchant) / FP_FACTOR))); } +short armorImageCount(fixpt enchant) { return (clamp((int)((enchant) / 3 / FP_FACTOR), 1, 5)); } short reflectionChance(fixpt enchant) { - const fixpt POW_REFLECT[] = { - // 0.85^x fixed point, with x from 0.25 to 50 in increments of 0.25: - 62926, 60421, 58015, 55705, 53487, 51358, 49313, 47349, 45464, 43654, 41916, 40247, 38644, 37106, 35628, 34210, 32848, 31540, 30284, 29078, 27920, - 26809, 25741, 24716, 23732, 22787, 21880, 21009, 20172, 19369, 18598, 17857, 17146, 16464, 15808, 15179, 14574, 13994, 13437, 12902, 12388, 11895, 11421, - 10967, 10530, 10111, 9708, 9321, 8950, 8594, 8252, 7923, 7608, 7305, 7014, 6735, 6466, 6209, 5962, 5724, 5496, 5278, 5067, 4866, 4672, 4486, 4307, 4136, - 3971, 3813, 3661, 3515, 3375, 3241, 3112, 2988, 2869, 2755, 2645, 2540, 2439, 2341, 2248, 2159, 2073, 1990, 1911, 1835, 1762, 1692, 1624, 1559, 1497, 1438, - 1380, 1325, 1273, 1222, 1173, 1127, 1082, 1039, 997, 958, 919, 883, 848, 814, 781, 750, 720, 692, 664, 638, 612, 588, 564, 542, 520, 500, 480, 461, 442, - 425, 408, 391, 376, 361, 346, 333, 319, 307, 294, 283, 271, 261, 250, 240, 231, 221, 213, 204, 196, 188, 181, 173, 166, 160, 153, 147, 141, 136, 130, 125, - 120, 115, 111, 106, 102, 98, 94, 90, 87, 83, 80, 77, 74, 71, 68, 65, 62, 60, 58, 55, 53, 51, 49, 47, 45, 43, 41, 40, 38, 37, 35, 34, 32, 31, 30, 29, 27, - 26, 25, 24, 23, 22, 21, 21, 20, 19}; + const fixpt POW_REFLECT[] = {// 0.85^x fixed point, with x from 0.25 to 50 in increments of 0.25: + 62926, 60421, 58015, 55705, 53487, 51358, 49313, 47349, 45464, 43654, 41916, 40247, 38644, 37106, 35628, 34210, 32848, 31540, 30284, 29078, 27920, 26809, 25741, 24716, 23732, 22787, 21880, 21009, 20172, + 19369, 18598, 17857, 17146, 16464, 15808, 15179, 14574, 13994, 13437, 12902, 12388, 11895, 11421, 10967, 10530, 10111, 9708, 9321, 8950, 8594, 8252, 7923, 7608, 7305, 7014, 6735, 6466, 6209, + 5962, 5724, 5496, 5278, 5067, 4866, 4672, 4486, 4307, 4136, 3971, 3813, 3661, 3515, 3375, 3241, 3112, 2988, 2869, 2755, 2645, 2540, 2439, 2341, 2248, 2159, 2073, 1990, 1911, + 1835, 1762, 1692, 1624, 1559, 1497, 1438, 1380, 1325, 1273, 1222, 1173, 1127, 1082, 1039, 997, 958, 919, 883, 848, 814, 781, 750, 720, 692, 664, 638, 612, 588, + 564, 542, 520, 500, 480, 461, 442, 425, 408, 391, 376, 361, 346, 333, 319, 307, 294, 283, 271, 261, 250, 240, 231, 221, 213, 204, 196, 188, 181, + 173, 166, 160, 153, 147, 141, 136, 130, 125, 120, 115, 111, 106, 102, 98, 94, 90, 87, 83, 80, 77, 74, 71, 68, 65, 62, 60, 58, 55, + 53, 51, 49, 47, 45, 43, 41, 40, 38, 37, 35, 34, 32, 31, 30, 29, 27, 26, 25, 24, 23, 22, 21, 21, 20, 19}; short idx = clamp(enchant * 4 / FP_FACTOR - 1, 0, LAST_INDEX(POW_REFLECT)); return clamp(100 - (100 * POW_REFLECT[idx] / FP_FACTOR), 1, 100); } long turnsForFullRegenInThousandths(fixpt bonus) { - const fixpt POW_REGEN[] = { - // 0.75^x fixed point, with x from -10 to 50 in increments of 1: - 1163770, 872827, 654620, 490965, 368224, 276168, 207126, 155344, 116508, 87381, 65536, 49152, 36864, 27648, 20736, 15552, 11664, 8748, 6561, 4920, 3690, - 2767, 2075, 1556, 1167, 875, 656, 492, 369, 277, 207, 155, 116, 87, 65, 49, 36, 27, 20, 15, 11, 8, 6, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + const fixpt POW_REGEN[] = {// 0.75^x fixed point, with x from -10 to 50 in increments of 1: + 1163770, 872827, 654620, 490965, 368224, 276168, 207126, 155344, 116508, 87381, 65536, 49152, 36864, 27648, 20736, 15552, 11664, 8748, 6561, 4920, 3690, 2767, 2075, 1556, 1167, 875, 656, 492, 369, 277, 207, + 155, 116, 87, 65, 49, 36, 27, 20, 15, 11, 8, 6, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // This will max out at full regeneration in about two turns. // This is the Syd nerf, after Syd broke the game over his knee with a +18 ring of regeneration. @@ -134,48 +123,42 @@ long turnsForFullRegenInThousandths(fixpt bonus) { return (1000 * TURNS_FOR_FULL_REGEN * POW_REGEN[idx] / FP_FACTOR) + 2000; } - fixpt damageFraction(fixpt netEnchant) { - const fixpt POW_DAMAGE_FRACTION[] = { - // 1.065^x fixed point, with x representing a change in 0.25 weapon enchantment points, ranging from -20 to 50. - 18598, 18894, 19193, 19498, 19807, 20122, 20441, 20765, 21095, 21430, 21770, 22115, 22466, 22823, 23185, 23553, 23926, 24306, 24692, 25084, 25482, 25886, - 26297, 26714, 27138, 27569, 28006, 28451, 28902, 29361, 29827, 30300, 30781, 31269, 31765, 32269, 32781, 33302, 33830, 34367, 34912, 35466, 36029, 36601, - 37182, 37772, 38371, 38980, 39598, 40227, 40865, 41514, 42172, 42842, 43521, 44212, 44914, 45626, 46350, 47086, 47833, 48592, 49363, 50146, 50942, 51751, - 52572, 53406, 54253, 55114, 55989, 56877, 57780, 58697, 59628, 60574, 61536, 62512, 63504, 64512, 65536, 66575, 67632, 68705, 69795, 70903, 72028, 73171, - 74332, 75512, 76710, 77927, 79164, 80420, 81696, 82992, 84309, 85647, 87006, 88387, 89789, 91214, 92662, 94132, 95626, 97143, 98685, 100251, 101842, 103458, - 105099, 106767, 108461, 110182, 111931, 113707, 115511, 117344, 119206, 121098, 123020, 124972, 126955, 128969, 131016, 133095, 135207, 137352, 139532, - 141746, 143995, 146280, 148602, 150960, 153355, 155789, 158261, 160772, 163323, 165915, 168548, 171222, 173939, 176699, 179503, 182352, 185245, 188185, - 191171, 194205, 197286, 200417, 203597, 206828, 210110, 213444, 216831, 220272, 223767, 227318, 230925, 234589, 238312, 242094, 245935, 249838, 253802, - 257830, 261921, 266077, 270300, 274589, 278946, 283372, 287869, 292437, 297078, 301792, 306581, 311445, 316388, 321408, 326508, 331689, 336953, 342300, - 347731, 353249, 358855, 364549, 370334, 376211, 382180, 388245, 394406, 400664, 407022, 413481, 420042, 426707, 433479, 440357, 447345, 454443, 461655, - 468980, 476422, 483982, 491662, 499464, 507390, 515441, 523620, 531929, 540370, 548945, 557656, 566505, 575494, 584626, 593903, 603328, 612901, 622627, - 632507, 642544, 652740, 663098, 673620, 684309, 695168, 706199, 717406, 728790, 740354, 752102, 764037, 776161, 788477, 800989, 813699, 826611, 839728, - 853053, 866590, 880341, 894311, 908502, 922918, 937563, 952441, 967555, 982908, 998505, 1014350, 1030446, 1046797, 1063408, 1080282, 1097425, 1114839, - 1132529, 1150501, 1168757, 1187303, 1206144, 1225283, 1244726, 1264478, 1284543, 1304927, 1325634, 1346669, 1368039, 1389747, 1411800, 1434203, 1456961, - 1480081, 1503567, 1527426}; + const fixpt POW_DAMAGE_FRACTION[] + = {// 1.065^x fixed point, with x representing a change in 0.25 weapon enchantment points, ranging from -20 to 50. + 18598, 18894, 19193, 19498, 19807, 20122, 20441, 20765, 21095, 21430, 21770, 22115, 22466, 22823, 23185, 23553, 23926, 24306, 24692, 25084, 25482, 25886, 26297, 26714, + 27138, 27569, 28006, 28451, 28902, 29361, 29827, 30300, 30781, 31269, 31765, 32269, 32781, 33302, 33830, 34367, 34912, 35466, 36029, 36601, 37182, 37772, 38371, 38980, + 39598, 40227, 40865, 41514, 42172, 42842, 43521, 44212, 44914, 45626, 46350, 47086, 47833, 48592, 49363, 50146, 50942, 51751, 52572, 53406, 54253, 55114, 55989, 56877, + 57780, 58697, 59628, 60574, 61536, 62512, 63504, 64512, 65536, 66575, 67632, 68705, 69795, 70903, 72028, 73171, 74332, 75512, 76710, 77927, 79164, 80420, 81696, 82992, + 84309, 85647, 87006, 88387, 89789, 91214, 92662, 94132, 95626, 97143, 98685, 100251, 101842, 103458, 105099, 106767, 108461, 110182, 111931, 113707, 115511, 117344, 119206, 121098, + 123020, 124972, 126955, 128969, 131016, 133095, 135207, 137352, 139532, 141746, 143995, 146280, 148602, 150960, 153355, 155789, 158261, 160772, 163323, 165915, 168548, 171222, 173939, 176699, + 179503, 182352, 185245, 188185, 191171, 194205, 197286, 200417, 203597, 206828, 210110, 213444, 216831, 220272, 223767, 227318, 230925, 234589, 238312, 242094, 245935, 249838, 253802, 257830, + 261921, 266077, 270300, 274589, 278946, 283372, 287869, 292437, 297078, 301792, 306581, 311445, 316388, 321408, 326508, 331689, 336953, 342300, 347731, 353249, 358855, 364549, 370334, 376211, + 382180, 388245, 394406, 400664, 407022, 413481, 420042, 426707, 433479, 440357, 447345, 454443, 461655, 468980, 476422, 483982, 491662, 499464, 507390, 515441, 523620, 531929, 540370, 548945, + 557656, 566505, 575494, 584626, 593903, 603328, 612901, 622627, 632507, 642544, 652740, 663098, 673620, 684309, 695168, 706199, 717406, 728790, 740354, 752102, 764037, 776161, 788477, 800989, + 813699, 826611, 839728, 853053, 866590, 880341, 894311, 908502, 922918, 937563, 952441, 967555, 982908, 998505, 1014350, 1030446, 1046797, 1063408, 1080282, 1097425, 1114839, 1132529, 1150501, 1168757, + 1187303, 1206144, 1225283, 1244726, 1264478, 1284543, 1304927, 1325634, 1346669, 1368039, 1389747, 1411800, 1434203, 1456961, 1480081, 1503567, 1527426}; short idx = clamp(netEnchant * 4 / FP_FACTOR + 80, 0, LAST_INDEX(POW_DAMAGE_FRACTION)); return POW_DAMAGE_FRACTION[idx]; } fixpt accuracyFraction(fixpt netEnchant) { - const fixpt POW_ACCURACY_FRACTION[] = { - // 1.065^x fixed point, with x representing a change in 0.25 weapon enchantment points (as displayed), ranging from -20 to 50. - 18598, 18894, 19193, 19498, 19807, 20122, 20441, 20765, 21095, 21430, 21770, 22115, 22466, 22823, 23185, 23553, 23926, 24306, 24692, 25084, 25482, 25886, - 26297, 26714, 27138, 27569, 28006, 28451, 28902, 29361, 29827, 30300, 30781, 31269, 31765, 32269, 32781, 33302, 33830, 34367, 34912, 35466, 36029, 36601, - 37182, 37772, 38371, 38980, 39598, 40227, 40865, 41514, 42172, 42842, 43521, 44212, 44914, 45626, 46350, 47086, 47833, 48592, 49363, 50146, 50942, 51751, - 52572, 53406, 54253, 55114, 55989, 56877, 57780, 58697, 59628, 60574, 61536, 62512, 63504, 64512, 65536, 66575, 67632, 68705, 69795, 70903, 72028, 73171, - 74332, 75512, 76710, 77927, 79164, 80420, 81696, 82992, 84309, 85647, 87006, 88387, 89789, 91214, 92662, 94132, 95626, 97143, 98685, 100251, 101842, 103458, - 105099, 106767, 108461, 110182, 111931, 113707, 115511, 117344, 119206, 121098, 123020, 124972, 126955, 128969, 131016, 133095, 135207, 137352, 139532, - 141746, 143995, 146280, 148602, 150960, 153355, 155789, 158261, 160772, 163323, 165915, 168548, 171222, 173939, 176699, 179503, 182352, 185245, 188185, - 191171, 194205, 197286, 200417, 203597, 206828, 210110, 213444, 216831, 220272, 223767, 227318, 230925, 234589, 238312, 242094, 245935, 249838, 253802, - 257830, 261921, 266077, 270300, 274589, 278946, 283372, 287869, 292437, 297078, 301792, 306581, 311445, 316388, 321408, 326508, 331689, 336953, 342300, - 347731, 353249, 358855, 364549, 370334, 376211, 382180, 388245, 394406, 400664, 407022, 413481, 420042, 426707, 433479, 440357, 447345, 454443, 461655, - 468980, 476422, 483982, 491662, 499464, 507390, 515441, 523620, 531929, 540370, 548945, 557656, 566505, 575494, 584626, 593903, 603328, 612901, 622627, - 632507, 642544, 652740, 663098, 673620, 684309, 695168, 706199, 717406, 728790, 740354, 752102, 764037, 776161, 788477, 800989, 813699, 826611, 839728, - 853053, 866590, 880341, 894311, 908502, 922918, 937563, 952441, 967555, 982908, 998505, 1014350, 1030446, 1046797, 1063408, 1080282, 1097425, 1114839, - 1132529, 1150501, 1168757, 1187303, 1206144, 1225283, 1244726, 1264478, 1284543, 1304927, 1325634, 1346669, 1368039, 1389747, 1411800, 1434203, 1456961, - 1480081, 1503567, 1527426}; + const fixpt POW_ACCURACY_FRACTION[] + = {// 1.065^x fixed point, with x representing a change in 0.25 weapon enchantment points (as displayed), + // ranging from -20 to 50. + 18598, 18894, 19193, 19498, 19807, 20122, 20441, 20765, 21095, 21430, 21770, 22115, 22466, 22823, 23185, 23553, 23926, 24306, 24692, 25084, 25482, 25886, 26297, 26714, + 27138, 27569, 28006, 28451, 28902, 29361, 29827, 30300, 30781, 31269, 31765, 32269, 32781, 33302, 33830, 34367, 34912, 35466, 36029, 36601, 37182, 37772, 38371, 38980, + 39598, 40227, 40865, 41514, 42172, 42842, 43521, 44212, 44914, 45626, 46350, 47086, 47833, 48592, 49363, 50146, 50942, 51751, 52572, 53406, 54253, 55114, 55989, 56877, + 57780, 58697, 59628, 60574, 61536, 62512, 63504, 64512, 65536, 66575, 67632, 68705, 69795, 70903, 72028, 73171, 74332, 75512, 76710, 77927, 79164, 80420, 81696, 82992, + 84309, 85647, 87006, 88387, 89789, 91214, 92662, 94132, 95626, 97143, 98685, 100251, 101842, 103458, 105099, 106767, 108461, 110182, 111931, 113707, 115511, 117344, 119206, 121098, + 123020, 124972, 126955, 128969, 131016, 133095, 135207, 137352, 139532, 141746, 143995, 146280, 148602, 150960, 153355, 155789, 158261, 160772, 163323, 165915, 168548, 171222, 173939, 176699, + 179503, 182352, 185245, 188185, 191171, 194205, 197286, 200417, 203597, 206828, 210110, 213444, 216831, 220272, 223767, 227318, 230925, 234589, 238312, 242094, 245935, 249838, 253802, 257830, + 261921, 266077, 270300, 274589, 278946, 283372, 287869, 292437, 297078, 301792, 306581, 311445, 316388, 321408, 326508, 331689, 336953, 342300, 347731, 353249, 358855, 364549, 370334, 376211, + 382180, 388245, 394406, 400664, 407022, 413481, 420042, 426707, 433479, 440357, 447345, 454443, 461655, 468980, 476422, 483982, 491662, 499464, 507390, 515441, 523620, 531929, 540370, 548945, + 557656, 566505, 575494, 584626, 593903, 603328, 612901, 622627, 632507, 642544, 652740, 663098, 673620, 684309, 695168, 706199, 717406, 728790, 740354, 752102, 764037, 776161, 788477, 800989, + 813699, 826611, 839728, 853053, 866590, 880341, 894311, 908502, 922918, 937563, 952441, 967555, 982908, 998505, 1014350, 1030446, 1046797, 1063408, 1080282, 1097425, 1114839, 1132529, 1150501, 1168757, + 1187303, 1206144, 1225283, 1244726, 1264478, 1284543, 1304927, 1325634, 1346669, 1368039, 1389747, 1411800, 1434203, 1456961, 1480081, 1503567, 1527426}; short idx = clamp(netEnchant * 4 / FP_FACTOR + 80, 0, LAST_INDEX(POW_ACCURACY_FRACTION)); return POW_ACCURACY_FRACTION[idx]; @@ -183,21 +166,18 @@ fixpt accuracyFraction(fixpt netEnchant) { fixpt defenseFraction(fixpt netDefense) { const fixpt POW_DEFENSE_FRACTION[] = { - // 0.877347265^x fixed point, with x representing a change in 0.25 armor points (as displayed), ranging from -20 to 50. - 897530, 868644, 840688, 813632, 787446, 762103, 737575, 713837, 690863, 668629, 647110, 626283, 606127, 586619, 567740, 549468, - 531784, 514669, 498105, 482074, 466559, 451543, 437011, 422946, 409334, 396160, 383410, 371071, 359128, 347570, 336384, 325558, - 315080, 304940, 295125, 285627, 276435, 267538, 258927, 250594, 242529, 234724, 227169, 219858, 212782, 205934, 199306, 192892, - 186684, 180676, 174861, 169233, 163786, 158515, 153414, 148476, 143698, 139073, 134597, 130265, 126073, 122015, 118088, 114288, - 110609, 107050, 103604, 100270, 97043, 93920, 90897, 87971, 85140, 82400, 79748, 77181, 74697, 72293, 69967, 67715, 65536, 63426, - 61385, 59409, 57497, 55647, 53856, 52123, 50445, 48822, 47250, 45730, 44258, 42833, 41455, 40121, 38829, 37580, 36370, 35200, 34067, - 32970, 31909, 30882, 29888, 28926, 27995, 27094, 26222, 25378, 24562, 23771, 23006, 22266, 21549, 20855, 20184, 19535, 18906, 18297, - 17709, 17139, 16587, 16053, 15536, 15036, 14552, 14084, 13631, 13192, 12768, 12357, 11959, 11574, 11201, 10841, 10492, 10154, 9828, - 9511, 9205, 8909, 8622, 8345, 8076, 7816, 7565, 7321, 7085, 6857, 6637, 6423, 6216, 6016, 5823, 5635, 5454, 5278, 5108, 4944, 4785, - 4631, 4482, 4337, 4198, 4063, 3932, 3805, 3683, 3564, 3450, 3339, 3231, 3127, 3026, 2929, 2835, 2744, 2655, 2570, 2487, 2407, 2329, - 2255, 2182, 2112, 2044, 1978, 1914, 1853, 1793, 1735, 1679, 1625, 1573, 1522, 1473, 1426, 1380, 1336, 1293, 1251, 1211, 1172, 1134, - 1097, 1062, 1028, 995, 963, 932, 902, 873, 845, 817, 791, 766, 741, 717, 694, 672, 650, 629, 609, 589, 570, 552, 534, 517, 500, 484, - 469, 453, 439, 425, 411, 398, 385, 373, 361, 349, 338, 327, 316, 306, 296, 287, 277, 268, 260, 251, 243, 235, 228, 221, 213, 207, - 200, 193, 187, 181, 175, 170, 164, 159, 154, 149, 144, 139, 135, 130, 126, 122, 118, 114, 111, 107, 104, 100, 97, 94}; + // 0.877347265^x fixed point, with x representing a change in 0.25 armor points (as displayed), ranging from -20 + // to 50. + 897530, 868644, 840688, 813632, 787446, 762103, 737575, 713837, 690863, 668629, 647110, 626283, 606127, 586619, 567740, 549468, 531784, 514669, 498105, 482074, 466559, 451543, 437011, 422946, 409334, 396160, 383410, 371071, 359128, + 347570, 336384, 325558, 315080, 304940, 295125, 285627, 276435, 267538, 258927, 250594, 242529, 234724, 227169, 219858, 212782, 205934, 199306, 192892, 186684, 180676, 174861, 169233, 163786, 158515, 153414, 148476, 143698, 139073, + 134597, 130265, 126073, 122015, 118088, 114288, 110609, 107050, 103604, 100270, 97043, 93920, 90897, 87971, 85140, 82400, 79748, 77181, 74697, 72293, 69967, 67715, 65536, 63426, 61385, 59409, 57497, 55647, 53856, + 52123, 50445, 48822, 47250, 45730, 44258, 42833, 41455, 40121, 38829, 37580, 36370, 35200, 34067, 32970, 31909, 30882, 29888, 28926, 27995, 27094, 26222, 25378, 24562, 23771, 23006, 22266, 21549, 20855, + 20184, 19535, 18906, 18297, 17709, 17139, 16587, 16053, 15536, 15036, 14552, 14084, 13631, 13192, 12768, 12357, 11959, 11574, 11201, 10841, 10492, 10154, 9828, 9511, 9205, 8909, 8622, 8345, 8076, + 7816, 7565, 7321, 7085, 6857, 6637, 6423, 6216, 6016, 5823, 5635, 5454, 5278, 5108, 4944, 4785, 4631, 4482, 4337, 4198, 4063, 3932, 3805, 3683, 3564, 3450, 3339, 3231, 3127, + 3026, 2929, 2835, 2744, 2655, 2570, 2487, 2407, 2329, 2255, 2182, 2112, 2044, 1978, 1914, 1853, 1793, 1735, 1679, 1625, 1573, 1522, 1473, 1426, 1380, 1336, 1293, 1251, 1211, + 1172, 1134, 1097, 1062, 1028, 995, 963, 932, 902, 873, 845, 817, 791, 766, 741, 717, 694, 672, 650, 629, 609, 589, 570, 552, 534, 517, 500, 484, 469, + 453, 439, 425, 411, 398, 385, 373, 361, 349, 338, 327, 316, 306, 296, 287, 277, 268, 260, 251, 243, 235, 228, 221, 213, 207, 200, 193, 187, 181, + 175, 170, 164, 159, 154, 149, 144, 139, 135, 130, 126, 122, 118, 114, 111, 107, 104, 100, 97, 94}; short idx = clamp(netDefense * 4 / 10 / FP_FACTOR + 80, 0, LAST_INDEX(POW_DEFENSE_FRACTION)); return POW_DEFENSE_FRACTION[idx]; @@ -212,86 +192,75 @@ short charmEffectDuration(short charmKind, short enchant) { short charmRechargeDelay(short charmKind, short enchant) { enchant = clamp(enchant, 1, 50); - short delay = charmEffectDuration(charmKind, enchant) - + (charmEffectTable[charmKind].rechargeDelayDuration * fp_pow(charmEffectTable[charmKind].rechargeDelayBase, enchant) / FP_FACTOR); + short delay = charmEffectDuration(charmKind, enchant) + (charmEffectTable[charmKind].rechargeDelayDuration * fp_pow(charmEffectTable[charmKind].rechargeDelayBase, enchant) / FP_FACTOR); return max(charmEffectTable[charmKind].rechargeDelayMinTurns, delay); } short runicWeaponChance(item *theItem, boolean customEnchantLevel, fixpt enchantLevel) { - const fixpt POW_16_RUNIC_DECREMENT[] = { // (1-0.16)^x fixed point, with x from 0 to 50 in increments of 0.25: - 65536, 62740, 60064, 57502, 55050, 52702, 50454, 48302, 46242, 44269, 42381, 40574, 38843, 37186, 35600, 34082, 32628, 31236, 29904, - 28629, 27407, 26238, 25119, 24048, 23022, 22040, 21100, 20200, 19339, 18514, 17724, 16968, 16244, 15551, 14888, 14253, 13645, 13063, - 12506, 11972, 11462, 10973, 10505, 10057, 9628, 9217, 8824, 8448, 8087, 7742, 7412, 7096, 6793, 6503, 6226, 5961, 5706, 5463, 5230, - 5007, 4793, 4589, 4393, 4206, 4026, 3854, 3690, 3533, 3382, 3238, 3100, 2967, 2841, 2720, 2604, 2492, 2386, 2284, 2187, 2094, 2004, - 1919, 1837, 1759, 1684, 1612, 1543, 1477, 1414, 1354, 1296, 1241, 1188, 1137, 1089, 1042, 998, 955, 914, 875, 838, 802, 768, 735, - 704, 674, 645, 617, 591, 566, 542, 519, 496, 475, 455, 436, 417, 399, 382, 366, 350, 335, 321, 307, 294, 281, 269, 258, 247, 236, - 226, 217, 207, 198, 190, 182, 174, 167, 159, 153, 146, 140, 134, 128, 123, 117, 112, 108, 103, 99, 94, 90, 86, 83, 79, 76, 73, 69, - 66, 64, 61, 58, 56, 53, 51, 49, 47, 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 18, 17, 16, - 15, 15, 14, 13, 13, 12, 12, 11, 11, 10}; - const fixpt POW_15_RUNIC_DECREMENT[] = { // (1-0.15)^x fixed point, with x from 0 to 50 in increments of 0.25: - 65536, 62926, 60421, 58015, 55705, 53487, 51358, 49313, 47349, 45464, 43654, 41916, 40247, 38644, 37106, 35628, 34210, 32848, 31540, - 30284, 29078, 27920, 26809, 25741, 24716, 23732, 22787, 21880, 21009, 20172, 19369, 18598, 17857, 17146, 16464, 15808, 15179, 14574, - 13994, 13437, 12902, 12388, 11895, 11421, 10967, 10530, 10111, 9708, 9321, 8950, 8594, 8252, 7923, 7608, 7305, 7014, 6735, 6466, 6209, - 5962, 5724, 5496, 5278, 5067, 4866, 4672, 4486, 4307, 4136, 3971, 3813, 3661, 3515, 3375, 3241, 3112, 2988, 2869, 2755, 2645, 2540, - 2439, 2341, 2248, 2159, 2073, 1990, 1911, 1835, 1762, 1692, 1624, 1559, 1497, 1438, 1380, 1325, 1273, 1222, 1173, 1127, 1082, 1039, - 997, 958, 919, 883, 848, 814, 781, 750, 720, 692, 664, 638, 612, 588, 564, 542, 520, 500, 480, 461, 442, 425, 408, 391, 376, 361, 346, - 333, 319, 307, 294, 283, 271, 261, 250, 240, 231, 221, 213, 204, 196, 188, 181, 173, 166, 160, 153, 147, 141, 136, 130, 125, 120, 115, - 111, 106, 102, 98, 94, 90, 87, 83, 80, 77, 74, 71, 68, 65, 62, 60, 58, 55, 53, 51, 49, 47, 45, 43, 41, 40, 38, 37, 35, 34, 32, 31, 30, - 29, 27, 26, 25, 24, 23, 22, 21, 21, 20, 19}; - const fixpt POW_14_RUNIC_DECREMENT[] = { // (1-0.14)^x fixed point, with x from 0 to 50 in increments of 0.25: - 65536, 63110, 60775, 58526, 56360, 54275, 52267, 50332, 48470, 46676, 44949, 43286, 41684, 40142, 38656, 37226, 35848, 34522, 33244, - 32014, 30829, 29689, 28590, 27532, 26513, 25532, 24587, 23677, 22801, 21958, 21145, 20363, 19609, 18883, 18185, 17512, 16864, 16240, - 15639, 15060, 14503, 13966, 13449, 12952, 12472, 12011, 11566, 11138, 10726, 10329, 9947, 9579, 9224, 8883, 8554, 8238, 7933, 7639, - 7357, 7084, 6822, 6570, 6327, 6092, 5867, 5650, 5441, 5239, 5046, 4859, 4679, 4506, 4339, 4179, 4024, 3875, 3732, 3593, 3460, 3332, - 3209, 3090, 2976, 2866, 2760, 2658, 2559, 2465, 2373, 2285, 2201, 2119, 2041, 1965, 1893, 1823, 1755, 1690, 1628, 1567, 1509, 1454, - 1400, 1348, 1298, 1250, 1204, 1159, 1116, 1075, 1035, 997, 960, 924, 890, 857, 825, 795, 765, 737, 710, 684, 658, 634, 610, 588, 566, - 545, 525, 505, 487, 469, 451, 435, 418, 403, 388, 374, 360, 346, 334, 321, 309, 298, 287, 276, 266, 256, 247, 237, 229, 220, 212, 204, - 197, 189, 182, 176, 169, 163, 157, 151, 145, 140, 135, 130, 125, 120, 116, 111, 107, 103, 99, 96, 92, 89, 85, 82, 79, 76, 73, 71, 68, - 66, 63, 61, 58, 56, 54, 52, 50, 48, 47, 45, 43, 42, 40, 38, 37, 36, 34}; - const fixpt POW_11_RUNIC_DECREMENT[] = { // (1-0.11)^x fixed point, with x from 0 to 50 in increments of 0.25: - 65536, 63654, 61826, 60051, 58327, 56652, 55025, 53445, 51911, 50420, 48972, 47566, 46200, 44874, 43585, 42334, 41118, 39938, 38791, - 37677, 36595, 35544, 34524, 33533, 32570, 31634, 30726, 29844, 28987, 28155, 27346, 26561, 25798, 25058, 24338, 23639, 22960, 22301, - 21661, 21039, 20435, 19848, 19278, 18725, 18187, 17665, 17157, 16665, 16186, 15721, 15270, 14832, 14406, 13992, 13590, 13200, 12821, - 12453, 12095, 11748, 11411, 11083, 10765, 10456, 10155, 9864, 9581, 9305, 9038, 8779, 8527, 8282, 8044, 7813, 7589, 7371, 7159, 6954, - 6754, 6560, 6372, 6189, 6011, 5838, 5671, 5508, 5350, 5196, 5047, 4902, 4761, 4624, 4492, 4363, 4237, 4116, 3997, 3883, 3771, 3663, - 3558, 3456, 3356, 3260, 3166, 3075, 2987, 2901, 2818, 2737, 2658, 2582, 2508, 2436, 2366, 2298, 2232, 2168, 2106, 2045, 1986, 1929, - 1874, 1820, 1768, 1717, 1668, 1620, 1573, 1528, 1484, 1442, 1400, 1360, 1321, 1283, 1246, 1210, 1176, 1142, 1109, 1077, 1046, 1016, - 987, 959, 931, 904, 878, 853, 829, 805, 782, 759, 737, 716, 696, 676, 656, 637, 619, 601, 584, 567, 551, 535, 520, 505, 490, 476, 462, - 449, 436, 424, 412, 400, 388, 377, 366, 356, 345, 336, 326, 317, 307, 299, 290, 282, 274, 266, 258, 251, 243, 236, 230, 223, 217, 210, - 204, 198, 193}; - const fixpt POW_7_RUNIC_DECREMENT[] = { // (1-0.07)^x fixed point, with x from 0 to 50 in increments of 0.25: - 65536, 64357, 63200, 62064, 60948, 59852, 58776, 57719, 56682, 55662, 54662, 53679, 52714, 51766, 50835, 49921, 49024, 48142, 47277, - 46427, 45592, 44772, 43967, 43177, 42401, 41638, 40890, 40155, 39433, 38724, 38027, 37344, 36672, 36013, 35365, 34730, 34105, 33492, - 32890, 32298, 31718, 31147, 30587, 30038, 29497, 28967, 28446, 27935, 27433, 26939, 26455, 25979, 25512, 25054, 24603, 24161, 23726, - 23300, 22881, 22470, 22066, 21669, 21279, 20897, 20521, 20152, 19790, 19434, 19084, 18741, 18404, 18073, 17748, 17429, 17116, 16808, - 16506, 16209, 15918, 15632, 15351, 15075, 14804, 14537, 14276, 14019, 13767, 13520, 13277, 13038, 12804, 12573, 12347, 12125, 11907, - 11693, 11483, 11276, 11074, 10875, 10679, 10487, 10299, 10113, 9931, 9753, 9578, 9405, 9236, 9070, 8907, 8747, 8590, 8435, 8284, 8135, - 7988, 7845, 7704, 7565, 7429, 7296, 7164, 7036, 6909, 6785, 6663, 6543, 6425, 6310, 6196, 6085, 5976, 5868, 5763, 5659, 5557, 5457, - 5359, 5263, 5168, 5075, 4984, 4894, 4806, 4720, 4635, 4552, 4470, 4390, 4311, 4233, 4157, 4082, 4009, 3937, 3866, 3796, 3728, 3661, - 3595, 3531, 3467, 3405, 3344, 3283, 3224, 3166, 3110, 3054, 2999, 2945, 2892, 2840, 2789, 2739, 2689, 2641, 2594, 2547, 2501, 2456, - 2412, 2369, 2326, 2284, 2243, 2203, 2163, 2124, 2086, 2048, 2012, 1975, 1940, 1905, 1871, 1837, 1804, 1772, 1740}; - const fixpt POW_6_RUNIC_DECREMENT[] = { // (1-0.06)^x fixed point, with x from 0 to 50 in increments of 0.25: - 65536, 64530, 63539, 62564, 61603, 60658, 59727, 58810, 57907, 57018, 56143, 55281, 54433, 53597, 52774, 51964, 51167, 50381, 49608, - 48846, 48097, 47358, 46631, 45916, 45211, 44517, 43833, 43161, 42498, 41846, 41203, 40571, 39948, 39335, 38731, 38137, 37551, 36975, - 36407, 35848, 35298, 34756, 34223, 33698, 33180, 32671, 32169, 31676, 31189, 30711, 30239, 29775, 29318, 28868, 28425, 27989, 27559, - 27136, 26719, 26309, 25905, 25508, 25116, 24731, 24351, 23977, 23609, 23247, 22890, 22539, 22193, 21852, 21516, 21186, 20861, 20541, - 20225, 19915, 19609, 19308, 19012, 18720, 18433, 18150, 17871, 17597, 17327, 17061, 16799, 16541, 16287, 16037, 15791, 15549, 15310, - 15075, 14843, 14616, 14391, 14170, 13953, 13739, 13528, 13320, 13116, 12914, 12716, 12521, 12329, 12139, 11953, 11770, 11589, 11411, - 11236, 11063, 10894, 10726, 10562, 10400, 10240, 10083, 9928, 9776, 9625, 9478, 9332, 9189, 9048, 8909, 8772, 8638, 8505, 8374, 8246, - 8119, 7995, 7872, 7751, 7632, 7515, 7400, 7286, 7174, 7064, 6956, 6849, 6744, 6640, 6538, 6438, 6339, 6242, 6146, 6052, 5959, 5867, - 5777, 5688, 5601, 5515, 5430, 5347, 5265, 5184, 5105, 5026, 4949, 4873, 4798, 4725, 4652, 4581, 4510, 4441, 4373, 4306, 4240, 4175, - 4111, 4047, 3985, 3924, 3864, 3805, 3746, 3689, 3632, 3576, 3521, 3467, 3414, 3362, 3310, 3259, 3209, 3160, 3111, 3064, 3017, 2970}; - const fixpt *effectChances[NUMBER_WEAPON_RUNIC_KINDS] = { - POW_16_RUNIC_DECREMENT, // W_SPEED - POW_6_RUNIC_DECREMENT, // W_QUIETUS - POW_7_RUNIC_DECREMENT, // W_PARALYSIS - POW_15_RUNIC_DECREMENT, // W_MULTIPLICITY - POW_14_RUNIC_DECREMENT, // W_SLOWING - POW_11_RUNIC_DECREMENT, // W_CONFUSION - POW_15_RUNIC_DECREMENT, // W_FORCE - 0, // W_SLAYING - 0, // W_MERCY - 0}; // W_PLENTY + const fixpt POW_16_RUNIC_DECREMENT[] + = {// (1-0.16)^x fixed point, with x from 0 to 50 in increments of 0.25: + 65536, 62740, 60064, 57502, 55050, 52702, 50454, 48302, 46242, 44269, 42381, 40574, 38843, 37186, 35600, 34082, 32628, 31236, 29904, 28629, 27407, 26238, 25119, 24048, 23022, 22040, 21100, 20200, 19339, + 18514, 17724, 16968, 16244, 15551, 14888, 14253, 13645, 13063, 12506, 11972, 11462, 10973, 10505, 10057, 9628, 9217, 8824, 8448, 8087, 7742, 7412, 7096, 6793, 6503, 6226, 5961, 5706, 5463, + 5230, 5007, 4793, 4589, 4393, 4206, 4026, 3854, 3690, 3533, 3382, 3238, 3100, 2967, 2841, 2720, 2604, 2492, 2386, 2284, 2187, 2094, 2004, 1919, 1837, 1759, 1684, 1612, 1543, + 1477, 1414, 1354, 1296, 1241, 1188, 1137, 1089, 1042, 998, 955, 914, 875, 838, 802, 768, 735, 704, 674, 645, 617, 591, 566, 542, 519, 496, 475, 455, 436, + 417, 399, 382, 366, 350, 335, 321, 307, 294, 281, 269, 258, 247, 236, 226, 217, 207, 198, 190, 182, 174, 167, 159, 153, 146, 140, 134, 128, 123, + 117, 112, 108, 103, 99, 94, 90, 86, 83, 79, 76, 73, 69, 66, 64, 61, 58, 56, 53, 51, 49, 47, 45, 43, 41, 39, 37, 36, 34, + 33, 31, 30, 29, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 18, 17, 16, 15, 15, 14, 13, 13, 12, 12, 11, 11, 10}; + const fixpt POW_15_RUNIC_DECREMENT[] + = {// (1-0.15)^x fixed point, with x from 0 to 50 in increments of 0.25: + 65536, 62926, 60421, 58015, 55705, 53487, 51358, 49313, 47349, 45464, 43654, 41916, 40247, 38644, 37106, 35628, 34210, 32848, 31540, 30284, 29078, 27920, 26809, 25741, 24716, 23732, 22787, 21880, 21009, + 20172, 19369, 18598, 17857, 17146, 16464, 15808, 15179, 14574, 13994, 13437, 12902, 12388, 11895, 11421, 10967, 10530, 10111, 9708, 9321, 8950, 8594, 8252, 7923, 7608, 7305, 7014, 6735, 6466, + 6209, 5962, 5724, 5496, 5278, 5067, 4866, 4672, 4486, 4307, 4136, 3971, 3813, 3661, 3515, 3375, 3241, 3112, 2988, 2869, 2755, 2645, 2540, 2439, 2341, 2248, 2159, 2073, 1990, + 1911, 1835, 1762, 1692, 1624, 1559, 1497, 1438, 1380, 1325, 1273, 1222, 1173, 1127, 1082, 1039, 997, 958, 919, 883, 848, 814, 781, 750, 720, 692, 664, 638, 612, + 588, 564, 542, 520, 500, 480, 461, 442, 425, 408, 391, 376, 361, 346, 333, 319, 307, 294, 283, 271, 261, 250, 240, 231, 221, 213, 204, 196, 188, + 181, 173, 166, 160, 153, 147, 141, 136, 130, 125, 120, 115, 111, 106, 102, 98, 94, 90, 87, 83, 80, 77, 74, 71, 68, 65, 62, 60, 58, + 55, 53, 51, 49, 47, 45, 43, 41, 40, 38, 37, 35, 34, 32, 31, 30, 29, 27, 26, 25, 24, 23, 22, 21, 21, 20, 19}; + const fixpt POW_14_RUNIC_DECREMENT[] + = {// (1-0.14)^x fixed point, with x from 0 to 50 in increments of 0.25: + 65536, 63110, 60775, 58526, 56360, 54275, 52267, 50332, 48470, 46676, 44949, 43286, 41684, 40142, 38656, 37226, 35848, 34522, 33244, 32014, 30829, 29689, 28590, 27532, 26513, 25532, 24587, 23677, 22801, + 21958, 21145, 20363, 19609, 18883, 18185, 17512, 16864, 16240, 15639, 15060, 14503, 13966, 13449, 12952, 12472, 12011, 11566, 11138, 10726, 10329, 9947, 9579, 9224, 8883, 8554, 8238, 7933, 7639, + 7357, 7084, 6822, 6570, 6327, 6092, 5867, 5650, 5441, 5239, 5046, 4859, 4679, 4506, 4339, 4179, 4024, 3875, 3732, 3593, 3460, 3332, 3209, 3090, 2976, 2866, 2760, 2658, 2559, + 2465, 2373, 2285, 2201, 2119, 2041, 1965, 1893, 1823, 1755, 1690, 1628, 1567, 1509, 1454, 1400, 1348, 1298, 1250, 1204, 1159, 1116, 1075, 1035, 997, 960, 924, 890, 857, + 825, 795, 765, 737, 710, 684, 658, 634, 610, 588, 566, 545, 525, 505, 487, 469, 451, 435, 418, 403, 388, 374, 360, 346, 334, 321, 309, 298, 287, + 276, 266, 256, 247, 237, 229, 220, 212, 204, 197, 189, 182, 176, 169, 163, 157, 151, 145, 140, 135, 130, 125, 120, 116, 111, 107, 103, 99, 96, + 92, 89, 85, 82, 79, 76, 73, 71, 68, 66, 63, 61, 58, 56, 54, 52, 50, 48, 47, 45, 43, 42, 40, 38, 37, 36, 34}; + const fixpt POW_11_RUNIC_DECREMENT[] + = {// (1-0.11)^x fixed point, with x from 0 to 50 in increments of 0.25: + 65536, 63654, 61826, 60051, 58327, 56652, 55025, 53445, 51911, 50420, 48972, 47566, 46200, 44874, 43585, 42334, 41118, 39938, 38791, 37677, 36595, 35544, 34524, 33533, 32570, 31634, 30726, 29844, 28987, + 28155, 27346, 26561, 25798, 25058, 24338, 23639, 22960, 22301, 21661, 21039, 20435, 19848, 19278, 18725, 18187, 17665, 17157, 16665, 16186, 15721, 15270, 14832, 14406, 13992, 13590, 13200, 12821, 12453, + 12095, 11748, 11411, 11083, 10765, 10456, 10155, 9864, 9581, 9305, 9038, 8779, 8527, 8282, 8044, 7813, 7589, 7371, 7159, 6954, 6754, 6560, 6372, 6189, 6011, 5838, 5671, 5508, 5350, + 5196, 5047, 4902, 4761, 4624, 4492, 4363, 4237, 4116, 3997, 3883, 3771, 3663, 3558, 3456, 3356, 3260, 3166, 3075, 2987, 2901, 2818, 2737, 2658, 2582, 2508, 2436, 2366, 2298, + 2232, 2168, 2106, 2045, 1986, 1929, 1874, 1820, 1768, 1717, 1668, 1620, 1573, 1528, 1484, 1442, 1400, 1360, 1321, 1283, 1246, 1210, 1176, 1142, 1109, 1077, 1046, 1016, 987, + 959, 931, 904, 878, 853, 829, 805, 782, 759, 737, 716, 696, 676, 656, 637, 619, 601, 584, 567, 551, 535, 520, 505, 490, 476, 462, 449, 436, 424, + 412, 400, 388, 377, 366, 356, 345, 336, 326, 317, 307, 299, 290, 282, 274, 266, 258, 251, 243, 236, 230, 223, 217, 210, 204, 198, 193}; + const fixpt POW_7_RUNIC_DECREMENT[] + = {// (1-0.07)^x fixed point, with x from 0 to 50 in increments of 0.25: + 65536, 64357, 63200, 62064, 60948, 59852, 58776, 57719, 56682, 55662, 54662, 53679, 52714, 51766, 50835, 49921, 49024, 48142, 47277, 46427, 45592, 44772, 43967, 43177, 42401, 41638, 40890, 40155, 39433, + 38724, 38027, 37344, 36672, 36013, 35365, 34730, 34105, 33492, 32890, 32298, 31718, 31147, 30587, 30038, 29497, 28967, 28446, 27935, 27433, 26939, 26455, 25979, 25512, 25054, 24603, 24161, 23726, 23300, + 22881, 22470, 22066, 21669, 21279, 20897, 20521, 20152, 19790, 19434, 19084, 18741, 18404, 18073, 17748, 17429, 17116, 16808, 16506, 16209, 15918, 15632, 15351, 15075, 14804, 14537, 14276, 14019, 13767, + 13520, 13277, 13038, 12804, 12573, 12347, 12125, 11907, 11693, 11483, 11276, 11074, 10875, 10679, 10487, 10299, 10113, 9931, 9753, 9578, 9405, 9236, 9070, 8907, 8747, 8590, 8435, 8284, 8135, + 7988, 7845, 7704, 7565, 7429, 7296, 7164, 7036, 6909, 6785, 6663, 6543, 6425, 6310, 6196, 6085, 5976, 5868, 5763, 5659, 5557, 5457, 5359, 5263, 5168, 5075, 4984, 4894, 4806, + 4720, 4635, 4552, 4470, 4390, 4311, 4233, 4157, 4082, 4009, 3937, 3866, 3796, 3728, 3661, 3595, 3531, 3467, 3405, 3344, 3283, 3224, 3166, 3110, 3054, 2999, 2945, 2892, 2840, + 2789, 2739, 2689, 2641, 2594, 2547, 2501, 2456, 2412, 2369, 2326, 2284, 2243, 2203, 2163, 2124, 2086, 2048, 2012, 1975, 1940, 1905, 1871, 1837, 1804, 1772, 1740}; + const fixpt POW_6_RUNIC_DECREMENT[] + = {// (1-0.06)^x fixed point, with x from 0 to 50 in increments of 0.25: + 65536, 64530, 63539, 62564, 61603, 60658, 59727, 58810, 57907, 57018, 56143, 55281, 54433, 53597, 52774, 51964, 51167, 50381, 49608, 48846, 48097, 47358, 46631, 45916, 45211, 44517, 43833, 43161, 42498, + 41846, 41203, 40571, 39948, 39335, 38731, 38137, 37551, 36975, 36407, 35848, 35298, 34756, 34223, 33698, 33180, 32671, 32169, 31676, 31189, 30711, 30239, 29775, 29318, 28868, 28425, 27989, 27559, 27136, + 26719, 26309, 25905, 25508, 25116, 24731, 24351, 23977, 23609, 23247, 22890, 22539, 22193, 21852, 21516, 21186, 20861, 20541, 20225, 19915, 19609, 19308, 19012, 18720, 18433, 18150, 17871, 17597, 17327, + 17061, 16799, 16541, 16287, 16037, 15791, 15549, 15310, 15075, 14843, 14616, 14391, 14170, 13953, 13739, 13528, 13320, 13116, 12914, 12716, 12521, 12329, 12139, 11953, 11770, 11589, 11411, 11236, 11063, + 10894, 10726, 10562, 10400, 10240, 10083, 9928, 9776, 9625, 9478, 9332, 9189, 9048, 8909, 8772, 8638, 8505, 8374, 8246, 8119, 7995, 7872, 7751, 7632, 7515, 7400, 7286, 7174, 7064, + 6956, 6849, 6744, 6640, 6538, 6438, 6339, 6242, 6146, 6052, 5959, 5867, 5777, 5688, 5601, 5515, 5430, 5347, 5265, 5184, 5105, 5026, 4949, 4873, 4798, 4725, 4652, 4581, 4510, + 4441, 4373, 4306, 4240, 4175, 4111, 4047, 3985, 3924, 3864, 3805, 3746, 3689, 3632, 3576, 3521, 3467, 3414, 3362, 3310, 3259, 3209, 3160, 3111, 3064, 3017, 2970}; + const fixpt *effectChances[NUMBER_WEAPON_RUNIC_KINDS] = {POW_16_RUNIC_DECREMENT, // W_SPEED + POW_6_RUNIC_DECREMENT, // W_QUIETUS + POW_7_RUNIC_DECREMENT, // W_PARALYSIS + POW_15_RUNIC_DECREMENT, // W_MULTIPLICITY + POW_14_RUNIC_DECREMENT, // W_SLOWING + POW_11_RUNIC_DECREMENT, // W_CONFUSION + POW_15_RUNIC_DECREMENT, // W_FORCE + 0, // W_SLAYING + 0, // W_MERCY + 0}; // W_PLENTY fixpt modifier; short runicType = theItem->enchant2; @@ -308,8 +277,7 @@ short runicWeaponChance(item *theItem, boolean customEnchantLevel, fixpt enchant } // Innately high-damage weapon types are less likely to trigger runic effects. - adjustedBaseDamage = (tableForItemCategory(theItem->category)[theItem->kind].range.lowerBound - + tableForItemCategory(theItem->category)[theItem->kind].range.upperBound) / 2; + adjustedBaseDamage = (tableForItemCategory(theItem->category)[theItem->kind].range.lowerBound + tableForItemCategory(theItem->category)[theItem->kind].range.upperBound) / 2; if (theItem->flags & ITEM_ATTACKS_STAGGER) { adjustedBaseDamage /= 2; // Normalize as though they attacked once per turn instead of every other turn. @@ -318,14 +286,14 @@ short runicWeaponChance(item *theItem, boolean customEnchantLevel, fixpt enchant // adjustedBaseDamage *= 2; // Normalize as though they attacked once per turn instead of twice per turn. // } // Testing disabling this for balance reasons... - modifier = FP_FACTOR - min((99 * FP_FACTOR)/100, (adjustedBaseDamage * FP_FACTOR) / 18); + modifier = FP_FACTOR - min((99 * FP_FACTOR) / 100, (adjustedBaseDamage * FP_FACTOR) / 18); if (enchantLevel < 0) { chance = 0; } else { tableIndex = enchantLevel * modifier * 4 / FP_FACTOR / FP_FACTOR; tableIndex = clamp(tableIndex, 0, LAST_INDEX(POW_16_RUNIC_DECREMENT)); - chance = 100 - (short) (100LL * effectChances[runicType][tableIndex] / FP_FACTOR); // good runic + chance = 100 - (short)(100LL * effectChances[runicType][tableIndex] / FP_FACTOR); // good runic } // Slow weapons get an adjusted chance of 1 - (1-p)^2 to reflect two bites at the apple instead of one. @@ -334,12 +302,12 @@ short runicWeaponChance(item *theItem, boolean customEnchantLevel, fixpt enchant } // Fast weapons get an adjusted chance of 1 - sqrt(1-p) to reflect one bite at the apple instead of two. if (theItem->flags & ITEM_ATTACKS_QUICKLY) { - chance = 100 * (FP_FACTOR - fp_sqrt(FP_FACTOR - (chance * FP_FACTOR)/100)) / FP_FACTOR; + chance = 100 * (FP_FACTOR - fp_sqrt(FP_FACTOR - (chance * FP_FACTOR) / 100)) / FP_FACTOR; } // The lowest percent change that a weapon will ever have is its enchantment level (if greater than 0). // That is so that even really heavy weapons will improve at least 1% per enchantment. - chance = clamp(chance, max(1, (short) (enchantLevel / FP_FACTOR)), 100); + chance = clamp(chance, max(1, (short)(enchantLevel / FP_FACTOR)), 100); return chance; } diff --git a/src/brogue/Recordings.c b/src/brogue/Recordings.c index dd6f56d9..92b7eedc 100644 --- a/src/brogue/Recordings.c +++ b/src/brogue/Recordings.c @@ -27,18 +27,13 @@ #include "GlobalsBase.h" #include "Globals.h" -#define RECORDING_HEADER_LENGTH 36 // bytes at the start of the recording file to store global data +#define RECORDING_HEADER_LENGTH 36 // bytes at the start of the recording file to store global data -static const long keystrokeTable[] = {UP_ARROW, LEFT_ARROW, DOWN_ARROW, RIGHT_ARROW, - ESCAPE_KEY, RETURN_KEY, DELETE_KEY, TAB_KEY, NUMPAD_0, NUMPAD_1, - NUMPAD_2, NUMPAD_3, NUMPAD_4, NUMPAD_5, NUMPAD_6, NUMPAD_7, NUMPAD_8, NUMPAD_9}; +static const long keystrokeTable[] = {UP_ARROW, LEFT_ARROW, DOWN_ARROW, RIGHT_ARROW, ESCAPE_KEY, RETURN_KEY, DELETE_KEY, TAB_KEY, NUMPAD_0, NUMPAD_1, NUMPAD_2, NUMPAD_3, NUMPAD_4, NUMPAD_5, NUMPAD_6, NUMPAD_7, NUMPAD_8, NUMPAD_9}; static const int keystrokeCount = sizeof(keystrokeTable) / sizeof(*keystrokeTable); -enum recordingSeekModes { - RECORDING_SEEK_MODE_TURN, - RECORDING_SEEK_MODE_DEPTH -}; +enum recordingSeekModes { RECORDING_SEEK_MODE_TURN, RECORDING_SEEK_MODE_DEPTH }; void recordChar(unsigned char c) { inputRecordBuffer[locationInRecordingBuffer++] = c; @@ -57,11 +52,11 @@ unsigned char compressKeystroke(long c) { for (i = 0; i < keystrokeCount; i++) { if (keystrokeTable[i] == c) { - return (unsigned char) (128 + i); + return (unsigned char)(128 + i); } } if (c < 256) { - return (unsigned char) c; + return (unsigned char)c; } return UNKNOWN_KEY; } @@ -71,7 +66,7 @@ void numberToString(uint64_t number, short numberOfBytes, unsigned char *recordT uint64_t n; n = number; - for (i=numberOfBytes - 1; i >= 0; i--) { + for (i = numberOfBytes - 1; i >= 0; i--) { recordTo[i] = n % 256; n /= 256; } @@ -84,7 +79,7 @@ void recordNumber(unsigned long number, short numberOfBytes) { unsigned char c[10]; numberToString(number, numberOfBytes, c); - for (i=0; ieventType); + recordChar((unsigned char)event->eventType); if (event->eventType == KEYSTROKE) { // record which key @@ -110,8 +105,8 @@ void recordEvent(rogueEvent *event) { } recordChar(c); } else { - recordChar((unsigned char) event->param1); - recordChar((unsigned char) event->param2); + recordChar((unsigned char)event->param1); + recordChar((unsigned char)event->param2); } // record the modifier keys @@ -149,7 +144,7 @@ void cancelKeystroke() { // record a series of keystrokes; string must end with a null terminator void recordKeystrokeSequence(unsigned char *keystrokeSequence) { short i; - for (i=0; keystrokeSequence[i] != '\0'; i++) { + for (i = 0; keystrokeSequence[i] != '\0'; i++) { recordKeystroke(keystrokeSequence[i], false, false); } } @@ -176,7 +171,7 @@ void writeHeaderInfo(char *path) { FILE *recordFile; // Zero out the entire header to start. - for (i=0; icontrolKey = (c & Fl(1)) ? true : false; - event->shiftKey = (c & Fl(2)) ? true : false; + event->shiftKey = (c & Fl(2)) ? true : false; } void loadNextAnnotation() { @@ -390,7 +386,7 @@ void loadNextAnnotation() { return; } - annotationFile = fopen(annotationPathname, "r"); + annotationFile = fopen(annotationPathname, "r"); fseek(annotationFile, rogue.locationInAnnotationFile, SEEK_SET); for (;;) { @@ -411,16 +407,14 @@ void loadNextAnnotation() { // load description fgets(rogue.nextAnnotation, 5000, annotationFile); - if (currentReadTurn > rogue.playerTurnNumber || - (currentReadTurn <= 1 && rogue.playerTurnNumber <= 1 && currentReadTurn >= rogue.playerTurnNumber)) { + if (currentReadTurn > rogue.playerTurnNumber || (currentReadTurn <= 1 && rogue.playerTurnNumber <= 1 && currentReadTurn >= rogue.playerTurnNumber)) { rogue.nextAnnotationTurn = currentReadTurn; // strip the newline off the end rogue.nextAnnotation[strlen(rogue.nextAnnotation) - 1] = '\0'; // strip out any gremlins in the annotation - for (i=0; i<5000 && rogue.nextAnnotation[i]; i++) { - if (rogue.nextAnnotation[i] < ' ' - || rogue.nextAnnotation[i] > '~') { + for (i = 0; i < 5000 && rogue.nextAnnotation[i]; i++) { + if (rogue.nextAnnotation[i] < ' ' || rogue.nextAnnotation[i] > '~') { rogue.nextAnnotation[i] = ' '; } } @@ -434,8 +428,7 @@ void loadNextAnnotation() { void displayAnnotation() { cellDisplayBuffer rbuf[COLS][ROWS]; - if (rogue.playbackMode - && rogue.playerTurnNumber == rogue.nextAnnotationTurn) { + if (rogue.playbackMode && rogue.playerTurnNumber == rogue.nextAnnotationTurn) { if (!rogue.playbackFastForward) { refreshSideBar(-1, -1, false); @@ -456,9 +449,7 @@ void displayAnnotation() { // Attempts to extract the patch version of versionString into patchVersion, // according to the global pattern. The Major and Minor versions must match ours. // Returns true if successful. -static boolean getPatchVersion(char *versionString, unsigned short *patchVersion) { - return sscanf(versionString, gameConst->patchVersionPattern, patchVersion) == 1; -} +static boolean getPatchVersion(char *versionString, unsigned short *patchVersion) { return sscanf(versionString, gameConst->patchVersionPattern, patchVersion) == 1; } // creates a game recording file, or if in playback mode, // initializes based on and starts reading from the recording file @@ -480,26 +471,26 @@ void initRecording() { RNGLogFile = fopen(RNG_LOG, "a"); #endif - locationInRecordingBuffer = 0; - positionInPlaybackFile = 0; - recordingLocation = 0; - maxLevelChanges = 0; - rogue.playbackOOS = false; - rogue.playbackOmniscience = false; - rogue.nextAnnotationTurn = 0; - rogue.nextAnnotation[0] = '\0'; - rogue.locationInAnnotationFile = 0; - rogue.patchVersion = 0; + locationInRecordingBuffer = 0; + positionInPlaybackFile = 0; + recordingLocation = 0; + maxLevelChanges = 0; + rogue.playbackOOS = false; + rogue.playbackOmniscience = false; + rogue.nextAnnotationTurn = 0; + rogue.nextAnnotation[0] = '\0'; + rogue.locationInAnnotationFile = 0; + rogue.patchVersion = 0; if (rogue.playbackMode) { - lengthOfPlaybackFile = 100000; // so recall functions don't freak out - rogue.playbackDelayPerTurn = DEFAULT_PLAYBACK_DELAY; + lengthOfPlaybackFile = 100000; // so recall functions don't freak out + rogue.playbackDelayPerTurn = DEFAULT_PLAYBACK_DELAY; rogue.playbackDelayThisTurn = rogue.playbackDelayPerTurn; - rogue.playbackPaused = false; + rogue.playbackPaused = false; fillBufferFromFile(); - for (i=0; i<15; i++) { + for (i = 0; i < 15; i++) { versionString[i] = recallChar(); } wizardMode = recallChar(); @@ -555,10 +546,10 @@ void initRecording() { rogue.gameExitStatusCode = EXIT_STATUS_FAILURE_RECORDING_WRONG_VERSION; } - rogue.seed = recallNumber(8); // master random seed - rogue.howManyTurns = recallNumber(4); // how many turns are in this recording - maxLevelChanges = recallNumber(4); // how many times the player changes depths - lengthOfPlaybackFile = recallNumber(4); + rogue.seed = recallNumber(8); // master random seed + rogue.howManyTurns = recallNumber(4); // how many turns are in this recording + maxLevelChanges = recallNumber(4); // how many times the player changes depths + lengthOfPlaybackFile = recallNumber(4); seedRandomGenerator(rogue.seed); previousGameSeed = rogue.seed; @@ -595,7 +586,7 @@ void OOSCheck(unsigned long x, short numberOfBytes) { printf("Event type mismatch in RNG check.\n"); playbackPanic(); } else if (recordedNumber != x) { - printf("Expected RNG output of %li; got %i.\n", recordedNumber, (int) x); + printf("Expected RNG output of %li; got %i.\n", recordedNumber, (int)x); playbackPanic(); } } @@ -614,11 +605,11 @@ void RNGCheck() { oldRNG = rogue.RNG; rogue.RNG = RNG_SUBSTANTIVE; -//#ifdef AUDIT_RNG -//reportRNGState(); -//#endif + //#ifdef AUDIT_RNG + // reportRNGState(); + //#endif - randomNumber = (unsigned long) rand_range(0, 255); + randomNumber = (unsigned long)rand_range(0, 255); OOSCheck(randomNumber, 1); rogue.RNG = oldRNG; @@ -634,37 +625,35 @@ boolean unpause() { return false; } -#define PLAYBACK_HELP_LINE_COUNT 20 +#define PLAYBACK_HELP_LINE_COUNT 20 void printPlaybackHelpScreen() { short i, j; cellDisplayBuffer dbuf[COLS][ROWS], rbuf[COLS][ROWS]; - char helpText[PLAYBACK_HELP_LINE_COUNT][80] = { - "Commands:", - "", - " : ****pause or unpause playback", - " k or up arrow: ****play back faster", - " j or down arrow: ****play back slower", - " <: ****go to previous level", - " >: ****go to next level", - " 0-9: ****skip to specified turn number", - "l or right arrow: ****advance one turn (shift for 5 turns; control for 20)", - "", - " : ****enable or disable omniscience", - " return: ****examine surroundings", - " i: ****display inventory", - " D: ****display discovered items", - " V: ****view saved recording", - " O: ****open and resume saved game", - " N: ****begin a new game", - " Q: ****quit to title screen", - "", - " -- press any key to continue --" - }; + char helpText[PLAYBACK_HELP_LINE_COUNT][80] = {"Commands:", + "", + " : ****pause or unpause playback", + " k or up arrow: ****play back faster", + " j or down arrow: ****play back slower", + " <: ****go to previous level", + " >: ****go to next level", + " 0-9: ****skip to specified turn number", + "l or right arrow: ****advance one turn (shift for 5 turns; control for 20)", + "", + " : ****enable or disable omniscience", + " return: ****examine surroundings", + " i: ****display inventory", + " D: ****display discovered items", + " V: ****view saved recording", + " O: ****open and resume saved game", + " N: ****begin a new game", + " Q: ****quit to title screen", + "", + " -- press any key to continue --"}; // Replace the "****"s with color escapes. - for (i=0; i 0) { avgTurnsPerLevel = rogue.howManyTurns / maxLevelChanges; } @@ -734,7 +723,7 @@ static void seek(unsigned long seekTarget, enum recordingSeekModes seekMode) { targetTurnNumber = rogue.playerTurnNumber + avgTurnsPerLevel; } break; - case RECORDING_SEEK_MODE_TURN : + case RECORDING_SEEK_MODE_TURN: if (seekTarget < rogue.playerTurnNumber) { startTurnNumber = 0; targetTurnNumber = seekTarget; @@ -751,12 +740,10 @@ static void seek(unsigned long seekTarget, enum recordingSeekModes seekMode) { } // there is no rewind, so start over at depth 1 - if ((seekMode == RECORDING_SEEK_MODE_TURN && seekTarget < rogue.playerTurnNumber) - || (seekMode == RECORDING_SEEK_MODE_DEPTH && seekTarget <= rogue.depthLevel)) { + if ((seekMode == RECORDING_SEEK_MODE_TURN && seekTarget < rogue.playerTurnNumber) || (seekMode == RECORDING_SEEK_MODE_DEPTH && seekTarget <= rogue.depthLevel)) { resetPlayback(); - if ((seekMode == RECORDING_SEEK_MODE_DEPTH && seekTarget == 1) - || (seekMode == RECORDING_SEEK_MODE_TURN && seekTarget == 0)) { + if ((seekMode == RECORDING_SEEK_MODE_DEPTH && seekTarget == 1) || (seekMode == RECORDING_SEEK_MODE_TURN && seekTarget == 0)) { arrivedAtDestination = true; } } @@ -772,14 +759,12 @@ static void seek(unsigned long seekTarget, enum recordingSeekModes seekMode) { while (!arrivedAtDestination && !rogue.gameHasEnded && !rogue.playbackOOS) { if (useProgressBar && !(rogue.playerTurnNumber % progressBarRefreshInterval)) { rogue.playbackFastForward = false; // so that pauseBrogue looks for inputs - printProgressBar((COLS - 20) / 2, ROWS / 2, "[ Loading... ]", - rogue.playerTurnNumber - startTurnNumber, - targetTurnNumber - startTurnNumber, &darkPurple, false); + printProgressBar((COLS - 20) / 2, ROWS / 2, "[ Loading... ]", rogue.playerTurnNumber - startTurnNumber, targetTurnNumber - startTurnNumber, &darkPurple, false); while (pauseBrogue(0)) { // pauseBrogue(0) is necessary to flush the display to the window in SDL if (rogue.gameHasEnded) { return; } - rogue.creaturesWillFlashThisTurn = false; // prevent monster flashes from showing up on screen + rogue.creaturesWillFlashThisTurn = false; // prevent monster flashes from showing up on screen nextBrogueEvent(&theEvent, true, false, true); // eat the input if it isn't clicking x } rogue.playbackFastForward = true; @@ -791,8 +776,7 @@ static void seek(unsigned long seekTarget, enum recordingSeekModes seekMode) { rogue.RNG = RNG_SUBSTANTIVE; executeEvent(&theEvent); - if ((seekMode == RECORDING_SEEK_MODE_DEPTH && rogue.depthLevel == seekTarget) - || (seekMode == RECORDING_SEEK_MODE_TURN && rogue.playerTurnNumber == seekTarget)) { + if ((seekMode == RECORDING_SEEK_MODE_DEPTH && rogue.depthLevel == seekTarget) || (seekMode == RECORDING_SEEK_MODE_TURN && rogue.playerTurnNumber == seekTarget)) { arrivedAtDestination = true; } @@ -837,16 +821,15 @@ void promptToAdvanceToLocation(short keystroke) { } void pausePlayback() { - //short oldRNG; + // short oldRNG; if (!rogue.playbackPaused) { rogue.playbackPaused = true; - messageWithColor(KEYBOARD_LABELS ? "recording paused. Press space to play." : "recording paused.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "recording paused. Press space to play." : "recording paused.", &teal, 0); refreshSideBar(-1, -1, false); - //oldRNG = rogue.RNG; - //rogue.RNG = RNG_SUBSTANTIVE; + // oldRNG = rogue.RNG; + // rogue.RNG = RNG_SUBSTANTIVE; mainInputLoop(); - //rogue.RNG = oldRNG; + // rogue.RNG = oldRNG; messageWithColor("recording unpaused.", &teal, 0); rogue.playbackPaused = false; refreshSideBar(-1, -1, false); @@ -877,7 +860,7 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { switch (key) { case UP_ARROW: case UP_KEY: - newDelay = max(1, min(rogue.playbackDelayPerTurn * 2/3, rogue.playbackDelayPerTurn - 1)); + newDelay = max(1, min(rogue.playbackDelayPerTurn * 2 / 3, rogue.playbackDelayPerTurn - 1)); if (newDelay != rogue.playbackDelayPerTurn) { flashTemporaryAlert(" Faster ", 300); } @@ -886,7 +869,7 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { return true; case DOWN_ARROW: case DOWN_KEY: - newDelay = min(3000, max(rogue.playbackDelayPerTurn * 3/2, rogue.playbackDelayPerTurn + 1)); + newDelay = min(3000, max(rogue.playbackDelayPerTurn * 3 / 2, rogue.playbackDelayPerTurn + 1)); if (newDelay != rogue.playbackDelayPerTurn) { flashTemporaryAlert(" Slower ", 300); } @@ -942,7 +925,7 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { } if (frameCount < 0) { - if ((unsigned long) (frameCount * -1) > rogue.playerTurnNumber) { + if ((unsigned long)(frameCount * -1) > rogue.playerTurnNumber) { destinationFrame = 0; } else { destinationFrame = rogue.playerTurnNumber + frameCount; @@ -1018,7 +1001,7 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { rogue.playbackMode = true; return true; case QUIT_KEY: - //freeEverything(); + // freeEverything(); rogue.gameHasEnded = true; rogue.gameExitStatusCode = EXIT_STATUS_SUCCESS; rogue.playbackOOS = false; @@ -1030,11 +1013,9 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { displayLevel(); refreshSideBar(-1, -1, false); if (rogue.trueColorMode) { - messageWithColor(KEYBOARD_LABELS ? "Color effects disabled. Press '\\' again to enable." : "Color effects disabled.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Color effects disabled. Press '\\' again to enable." : "Color effects disabled.", &teal, 0); } else { - messageWithColor(KEYBOARD_LABELS ? "Color effects enabled. Press '\\' again to disable." : "Color effects enabled.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Color effects enabled. Press '\\' again to disable." : "Color effects enabled.", &teal, 0); } return true; case STEALTH_RANGE_KEY: @@ -1042,11 +1023,9 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { displayLevel(); refreshSideBar(-1, -1, false); if (rogue.displayStealthRangeMode) { - messageWithColor(KEYBOARD_LABELS ? "Stealth range displayed. Press ']' again to hide." : "Stealth range displayed.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Stealth range displayed. Press ']' again to hide." : "Stealth range displayed.", &teal, 0); } else { - messageWithColor(KEYBOARD_LABELS ? "Stealth range hidden. Press ']' again to display." : "Stealth range hidden.", - &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Stealth range hidden. Press ']' again to display." : "Stealth range hidden.", &teal, 0); } return true; case GRAPHICS_KEY: @@ -1054,36 +1033,30 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { graphicsMode = setGraphicsMode((graphicsMode + 1) % 3); switch (graphicsMode) { case TEXT_GRAPHICS: - messageWithColor(KEYBOARD_LABELS - ? "Switched to text mode. Press 'G' again to enable tiles." - : "Switched to text mode.", &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Switched to text mode. Press 'G' again to enable tiles." : "Switched to text mode.", &teal, 0); break; case TILES_GRAPHICS: - messageWithColor(KEYBOARD_LABELS - ? "Switched to graphical tiles. Press 'G' again to enable hybrid mode." - : "Switched to graphical tiles.", &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Switched to graphical tiles. Press 'G' again to enable hybrid mode." : "Switched to graphical tiles.", &teal, 0); break; case HYBRID_GRAPHICS: - messageWithColor(KEYBOARD_LABELS - ? "Switched to hybrid mode. Press 'G' again to disable tiles." - : "Switched to hybrid mode.", &teal, 0); + messageWithColor(KEYBOARD_LABELS ? "Switched to hybrid mode. Press 'G' again to disable tiles." : "Switched to hybrid mode.", &teal, 0); break; } } return true; case SEED_KEY: - //rogue.playbackMode = false; - //DEBUG {displayGrid(safetyMap); displayMoreSign(); displayLevel();} - //rogue.playbackMode = true; + // rogue.playbackMode = false; + // DEBUG {displayGrid(safetyMap); displayMoreSign(); displayLevel();} + // rogue.playbackMode = true; printSeed(); return true; case SWITCH_TO_PLAYING_KEY: #ifdef ENABLE_PLAYBACK_SWITCH - if (!rogue.gameHasEnded && !rogue.playbackOOS) { - switchToPlaying(); - lengthOfPlaybackFile = recordingLocation; - } - return true; + if (!rogue.gameHasEnded && !rogue.playbackOOS) { + switchToPlaying(); + lengthOfPlaybackFile = recordingLocation; + } + return true; #endif return false; case ESCAPE_KEY: @@ -1093,8 +1066,7 @@ boolean executePlaybackInput(rogueEvent *recordingInput) { } return false; default: - if (key >= '0' && key <= '9' - || key >= NUMPAD_0 && key <= NUMPAD_9) { + if (key >= '0' && key <= '9' || key >= NUMPAD_0 && key <= NUMPAD_9) { promptToAdvanceToLocation(key); return true; @@ -1154,7 +1126,7 @@ void getDefaultFilePath(char *defaultPath, boolean gameOver) { // 32-bit numbers are printed in full // 64-bit numbers longer than 11 digits are shortened to e.g "184...51615" sprintf(seed, "%llu", (unsigned long long)rogue.seed); - if (strlen(seed) > 11) sprintf(seed+3, "...%05lu", (unsigned long)(rogue.seed % 100000)); + if (strlen(seed) > 11) sprintf(seed + 3, "...%05lu", (unsigned long)(rogue.seed % 100000)); if (serverMode) { // With WebBrogue, filenames must fit into 30 bytes, including extension and terminal \0. @@ -1213,8 +1185,7 @@ void saveGame() { deleteMessages(); do { askAgain = false; - if (getInputTextString(filePathWithoutSuffix, "Save game as ( to cancel): ", - BROGUE_FILENAME_MAX - strlen(GAME_SUFFIX), filePathWithoutSuffix, GAME_SUFFIX, TEXT_INPUT_FILENAME, false)) { + if (getInputTextString(filePathWithoutSuffix, "Save game as ( to cancel): ", BROGUE_FILENAME_MAX - strlen(GAME_SUFFIX), filePathWithoutSuffix, GAME_SUFFIX, TEXT_INPUT_FILENAME, false)) { snprintf(filePath, BROGUE_FILENAME_MAX, "%s%s", filePathWithoutSuffix, GAME_SUFFIX); if (!fileExists(filePath) || confirm("File of that name already exists. Overwrite?", true)) { remove(filePath); @@ -1261,8 +1232,7 @@ void saveRecording(char *filePathWithoutSuffix) { deleteMessages(); do { askAgain = false; - if (getInputTextString(filePathWithoutSuffix, "Save recording as ( to cancel): ", - BROGUE_FILENAME_MAX - strlen(RECORDING_SUFFIX), filePathWithoutSuffix, RECORDING_SUFFIX, TEXT_INPUT_FILENAME, false)) { + if (getInputTextString(filePathWithoutSuffix, "Save recording as ( to cancel): ", BROGUE_FILENAME_MAX - strlen(RECORDING_SUFFIX), filePathWithoutSuffix, RECORDING_SUFFIX, TEXT_INPUT_FILENAME, false)) { snprintf(filePath, BROGUE_FILENAME_MAX, "%s%s", filePathWithoutSuffix, RECORDING_SUFFIX); if (!fileExists(filePath) || confirm("File of that name already exists. Overwrite?", true)) { @@ -1272,7 +1242,8 @@ void saveRecording(char *filePathWithoutSuffix) { } else { askAgain = true; } - } else { // Declined to save recording; save it anyway as LastRecording, and delete LastRecording if it already exists. + } else { // Declined to save recording; save it anyway as LastRecording, and delete LastRecording if it already + // exists. snprintf(filePath, BROGUE_FILENAME_MAX, "%s%s", LAST_RECORDING_NAME, RECORDING_SUFFIX); if (fileExists(filePath)) { remove(filePath); @@ -1291,13 +1262,13 @@ void copyFile(char *fromFilePath, char *toFilePath, unsigned long fromFileLength remove(toFilePath); - fromFile = fopen(fromFilePath, "rb"); - toFile = fopen(toFilePath, "wb"); + fromFile = fopen(fromFilePath, "rb"); + toFile = fopen(toFilePath, "wb"); for (n = 0; n < fromFileLength; n += m) { m = min(INPUT_RECORD_BUFFER, fromFileLength - n); - fread((void *) fileBuffer, 1, m, fromFile); - fwrite((void *) fileBuffer, 1, m, toFile); + fread((void *)fileBuffer, 1, m, fromFile); + fwrite((void *)fileBuffer, 1, m, toFile); } fclose(fromFile); @@ -1311,11 +1282,11 @@ void switchToPlaying() { getAvailableFilePath(lastGamePath, LAST_GAME_NAME, GAME_SUFFIX); strcat(lastGamePath, GAME_SUFFIX); - rogue.playbackMode = false; - rogue.playbackFastForward = false; - rogue.playbackOmniscience = false; - rogue.recording = true; - locationInRecordingBuffer = 0; + rogue.playbackMode = false; + rogue.playbackFastForward = false; + rogue.playbackOmniscience = false; + rogue.recording = true; + locationInRecordingBuffer = 0; copyFile(currentFilePath, lastGamePath, recordingLocation); #ifndef ENABLE_PLAYBACK_SWITCH if (DELETE_SAVE_FILE_AFTER_LOADING) { @@ -1358,10 +1329,7 @@ boolean loadSavedGame() { overlayDisplayBuffer(dbuf, 0); rogue.playbackFastForward = true; - while (recordingLocation < lengthOfPlaybackFile - && rogue.playerTurnNumber < rogue.howManyTurns - && !rogue.gameHasEnded - && !rogue.playbackOOS) { + while (recordingLocation < lengthOfPlaybackFile && rogue.playerTurnNumber < rogue.howManyTurns && !rogue.gameHasEnded && !rogue.playbackOOS) { rogue.RNG = RNG_COSMETIC; nextBrogueEvent(&theEvent, false, true, false); @@ -1372,7 +1340,8 @@ boolean loadSavedGame() { if (recordingLocation / progressBarInterval != previousRecordingLocation / progressBarInterval && !rogue.playbackOOS) { rogue.playbackFastForward = false; // so that pauseBrogue looks for inputs printProgressBar((COLS - 20) / 2, ROWS / 2, "[ Loading... ]", recordingLocation, lengthOfPlaybackFile, &darkPurple, false); - while (pauseBrogue(0)) { // pauseBrogue(0) is necessary to flush the display to the window in SDL, as well as look for inputs + while (pauseBrogue(0)) { // pauseBrogue(0) is necessary to flush the display to the window in SDL, as + // well as look for inputs rogue.creaturesWillFlashThisTurn = false; // prevent monster flashes from showing up on screen nextBrogueEvent(&theEvent, true, false, true); if (rogue.gameHasEnded || theEvent.eventType == KEYSTROKE && theEvent.param1 == ESCAPE_KEY) { @@ -1397,28 +1366,20 @@ boolean loadSavedGame() { void describeKeystroke(unsigned char key, char *description) { short i; long c; - const long keyList[50] = {UP_KEY, DOWN_KEY, LEFT_KEY, RIGHT_KEY, UP_ARROW, LEFT_ARROW, - DOWN_ARROW, RIGHT_ARROW, UPLEFT_KEY, UPRIGHT_KEY, DOWNLEFT_KEY, DOWNRIGHT_KEY, - DESCEND_KEY, ASCEND_KEY, REST_KEY, AUTO_REST_KEY, SEARCH_KEY, INVENTORY_KEY, - ACKNOWLEDGE_KEY, EQUIP_KEY, UNEQUIP_KEY, APPLY_KEY, THROW_KEY, RELABEL_KEY, DROP_KEY, CALL_KEY, - //FIGHT_KEY, FIGHT_TO_DEATH_KEY, - BROGUE_HELP_KEY, DISCOVERIES_KEY, RETURN_KEY, - EXPLORE_KEY, AUTOPLAY_KEY, SEED_KEY, EASY_MODE_KEY, ESCAPE_KEY, - RETURN_KEY, DELETE_KEY, TAB_KEY, PERIOD_KEY, VIEW_RECORDING_KEY, NUMPAD_0, - NUMPAD_1, NUMPAD_2, NUMPAD_3, NUMPAD_4, NUMPAD_5, NUMPAD_6, NUMPAD_7, NUMPAD_8, - NUMPAD_9, UNKNOWN_KEY}; - const char descList[51][30] = {"up", "down", "left", "right", "up arrow", "left arrow", - "down arrow", "right arrow", "upleft", "upright", "downleft", "downright", - "descend", "ascend", "rest", "auto rest", "search", "inventory", "acknowledge", - "equip", "unequip", "apply", "throw", "relabel", "drop", "call", - //"fight", "fight to death", - "help", "discoveries", "repeat travel", "explore", "autoplay", "seed", - "easy mode", "escape", "return", "delete", "tab", "period", "open file", - "numpad 0", "numpad 1", "numpad 2", "numpad 3", "numpad 4", "numpad 5", "numpad 6", - "numpad 7", "numpad 8", "numpad 9", "unknown", "ERROR"}; + const long keyList[50] = {UP_KEY, DOWN_KEY, LEFT_KEY, RIGHT_KEY, UP_ARROW, LEFT_ARROW, DOWN_ARROW, RIGHT_ARROW, UPLEFT_KEY, UPRIGHT_KEY, DOWNLEFT_KEY, DOWNRIGHT_KEY, DESCEND_KEY, ASCEND_KEY, REST_KEY, AUTO_REST_KEY, SEARCH_KEY, + INVENTORY_KEY, ACKNOWLEDGE_KEY, EQUIP_KEY, UNEQUIP_KEY, APPLY_KEY, THROW_KEY, RELABEL_KEY, DROP_KEY, CALL_KEY, + // FIGHT_KEY, FIGHT_TO_DEATH_KEY, + BROGUE_HELP_KEY, DISCOVERIES_KEY, RETURN_KEY, EXPLORE_KEY, AUTOPLAY_KEY, SEED_KEY, EASY_MODE_KEY, ESCAPE_KEY, RETURN_KEY, DELETE_KEY, TAB_KEY, PERIOD_KEY, VIEW_RECORDING_KEY, NUMPAD_0, NUMPAD_1, NUMPAD_2, + NUMPAD_3, NUMPAD_4, NUMPAD_5, NUMPAD_6, NUMPAD_7, NUMPAD_8, NUMPAD_9, UNKNOWN_KEY}; + const char descList[51][30] = {"up", "down", "left", "right", "up arrow", "left arrow", "down arrow", "right arrow", "upleft", "upright", "downleft", "downright", "descend", "ascend", "rest", "auto rest", "search", "inventory", + "acknowledge", "equip", "unequip", "apply", "throw", "relabel", "drop", "call", + //"fight", "fight to death", + "help", "discoveries", "repeat travel", "explore", "autoplay", "seed", "easy mode", "escape", "return", "delete", "tab", "period", "open file", "numpad 0", "numpad 1", "numpad 2", "numpad 3", "numpad 4", + "numpad 5", "numpad 6", "numpad 7", "numpad 8", "numpad 9", "unknown", "ERROR"}; c = uncompressKeystroke(key); - for (i=0; i < 50 && keyList[i] != c; i++); + for (i = 0; i < 50 && keyList[i] != c; i++) + ; if (key >= 32 && key <= 126) { sprintf(description, "Key: %c\t(%s)", key, descList[i]); } else { @@ -1479,23 +1440,20 @@ void parseFile() { descriptionFile = fopen("Recording Description.txt", "w"); - for (i=0; i<16; i++) { + for (i = 0; i < 16; i++) { versionString[i] = recallChar(); } - seed = recallNumber(8); - numTurns = recallNumber(4); - numDepths = recallNumber(4); - fileLength = recallNumber(4); - - fprintf(descriptionFile, "Parsed file \"%s\":\n\tVersion: %s\n\tSeed: %lld\n\tNumber of turns: %lu\n\tNumber of depth changes: %lu\n\tFile length: %lu\n", - currentFilePath, - versionString, - (unsigned long long)seed, - numTurns, - numDepths, - fileLength); - for (i=0; recordingLocation < fileLength; i++) { + seed = recallNumber(8); + numTurns = recallNumber(4); + numDepths = recallNumber(4); + fileLength = recallNumber(4); + + fprintf(descriptionFile, + "Parsed file \"%s\":\n\tVersion: %s\n\tSeed: %lld\n\tNumber of turns: %lu\n\tNumber of depth changes: " + "%lu\n\tFile length: %lu\n", + currentFilePath, versionString, (unsigned long long)seed, numTurns, numDepths, fileLength); + for (i = 0; recordingLocation < fileLength; i++) { startLoc = recordingLocation; c = recallChar(); switch (c) { @@ -1506,19 +1464,19 @@ void parseFile() { case MOUSE_UP: case MOUSE_DOWN: case MOUSE_ENTERED_CELL: - x = (short) recallChar(); - y = (short) recallChar(); + x = (short)recallChar(); + y = (short)recallChar(); sprintf(description, "Mouse click: (%i, %i)", x, y); appendModifierKeyDescription(description); break; case RNG_CHECK: - sprintf(description, "\tRNG check: %i", (short) recallChar()); + sprintf(description, "\tRNG check: %i", (short)recallChar()); break; case SAVED_GAME_LOADED: strcpy(description, "Saved game loaded"); break; default: - sprintf(description, "UNKNOWN EVENT TYPE: %i", (short) c); + sprintf(description, "UNKNOWN EVENT TYPE: %i", (short)c); break; } fprintf(descriptionFile, "\nEvent %li, loc %li, length %li:%s\t%s", i, startLoc, recordingLocation - startLoc, (i < 10 ? " " : ""), description); diff --git a/src/brogue/Rogue.h b/src/brogue/Rogue.h index ab0e8e84..3e7cb2e1 100644 --- a/src/brogue/Rogue.h +++ b/src/brogue/Rogue.h @@ -48,80 +48,81 @@ #define STRINGIFY(x) _str(x) // Macro to compare BROGUE_MAJOR.BROGUE_MINOR.patchVersion to a.b.c -#define BROGUE_VERSION_ATLEAST(a,b,c) (BROGUE_MAJOR != (a) ? BROGUE_MAJOR > (a) : BROGUE_MINOR != (b) ? BROGUE_MINOR > (b) : rogue.patchVersion >= (c)) +#define BROGUE_VERSION_ATLEAST(a, b, c) (BROGUE_MAJOR != (a) ? BROGUE_MAJOR > (a) : BROGUE_MINOR != (b) ? BROGUE_MINOR > (b) : rogue.patchVersion >= (c)) -#define DEBUG if (rogue.wizard) -#define MONSTERS_ENABLED (!rogue.wizard || 1) // Quest room monsters can be generated regardless. -#define ITEMS_ENABLED (!rogue.wizard || 1) +#define DEBUG if (rogue.wizard) +#define MONSTERS_ENABLED (!rogue.wizard || 1) // Quest room monsters can be generated regardless. +#define ITEMS_ENABLED (!rogue.wizard || 1) -#define D_BULLET_TIME (rogue.wizard && 0) -#define D_WORMHOLING (rogue.wizard && 1) -#define D_IMMORTAL (rogue.wizard && 1) +#define D_BULLET_TIME (rogue.wizard && 0) +#define D_WORMHOLING (rogue.wizard && 1) +#define D_IMMORTAL (rogue.wizard && 1) -#define D_SAFETY_VISION (rogue.wizard && 0) -#define D_SCENT_VISION (rogue.wizard && 0) -#define D_DISABLE_BACKGROUND_COLORS (rogue.wizard && 0) -#define D_OMNISCENCE (rogue.wizard && 0) +#define D_SAFETY_VISION (rogue.wizard && 0) +#define D_SCENT_VISION (rogue.wizard && 0) +#define D_DISABLE_BACKGROUND_COLORS (rogue.wizard && 0) +#define D_OMNISCENCE (rogue.wizard && 0) -#define D_INSPECT_LEVELGEN (rogue.wizard && 0) -#define D_INSPECT_MACHINES (rogue.wizard && 0) +#define D_INSPECT_LEVELGEN (rogue.wizard && 0) +#define D_INSPECT_MACHINES (rogue.wizard && 0) -#define D_MESSAGE_ITEM_GENERATION (rogue.wizard && 0) -#define D_MESSAGE_MACHINE_GENERATION (rogue.wizard && 0) +#define D_MESSAGE_ITEM_GENERATION (rogue.wizard && 0) +#define D_MESSAGE_MACHINE_GENERATION (rogue.wizard && 0) // set to false to allow multiple loads from the same saved file: -#define DELETE_SAVE_FILE_AFTER_LOADING true +#define DELETE_SAVE_FILE_AFTER_LOADING true // set to false to disable references to keystrokes (e.g. for a tablet port) #define KEYBOARD_LABELS true //#define BROGUE_ASSERTS // introduces several assert()s -- useful to find certain array overruns and other bugs //#define AUDIT_RNG // VERY slow, but sometimes necessary to debug out-of-sync recording errors -//#define GENERATE_FONT_FILES // Displays font in grid upon startup, which can be screen-captured into font files for PC. +//#define GENERATE_FONT_FILES // Displays font in grid upon startup, which can be screen-captured into font files for +// PC. #ifdef BROGUE_ASSERTS #include -#define brogueAssert(x) assert(x) +#define brogueAssert(x) assert(x) #else #define brogueAssert(x) #endif -#define boolean char +#define boolean char -#define false 0 -#define true 1 +#define false 0 +#define true 1 -#define Fl(N) ((unsigned long) 1 << (N)) +#define Fl(N) ((unsigned long)1 << (N)) typedef long long fixpt; #define FP_BASE 16 // Don't change this without recalculating all of the power tables throughout the code! #define FP_FACTOR (1LL << FP_BASE) -#define FP_MUL(x, y) ((x) * (y) / FP_FACTOR) -#define FP_DIV(x, y) ((x) * FP_FACTOR / (y)) +#define FP_MUL(x, y) ((x) * (y) / FP_FACTOR) +#define FP_DIV(x, y) ((x)*FP_FACTOR / (y)) // recording and save filenames -#define LAST_GAME_NAME "LastGame" -#define LAST_RECORDING_NAME "LastRecording" -#define RECORDING_SUFFIX ".broguerec" -#define GAME_SUFFIX ".broguesave" -#define ANNOTATION_SUFFIX ".txt" -#define RNG_LOG "RNGLog.txt" -#define SCREENSHOT_SUFFIX ".png" +#define LAST_GAME_NAME "LastGame" +#define LAST_RECORDING_NAME "LastRecording" +#define RECORDING_SUFFIX ".broguerec" +#define GAME_SUFFIX ".broguesave" +#define ANNOTATION_SUFFIX ".txt" +#define RNG_LOG "RNGLog.txt" +#define SCREENSHOT_SUFFIX ".png" -#define BROGUE_FILENAME_MAX (min(1024*4, FILENAME_MAX)) +#define BROGUE_FILENAME_MAX (min(1024 * 4, FILENAME_MAX)) // Date format used when listing recordings and high scores -#define DATE_FORMAT "%Y-%m-%d" // see strftime() documentation +#define DATE_FORMAT "%Y-%m-%d" // see strftime() documentation -#define MESSAGE_LINES 3 +#define MESSAGE_LINES 3 #define MESSAGE_ARCHIVE_VIEW_LINES ROWS -#define MESSAGE_ARCHIVE_LINES (MESSAGE_ARCHIVE_VIEW_LINES*10) -#define MESSAGE_ARCHIVE_ENTRIES (MESSAGE_ARCHIVE_LINES*4) -#define MAX_MESSAGE_REPEATS 100 +#define MESSAGE_ARCHIVE_LINES (MESSAGE_ARCHIVE_VIEW_LINES * 10) +#define MESSAGE_ARCHIVE_ENTRIES (MESSAGE_ARCHIVE_LINES * 4) +#define MAX_MESSAGE_REPEATS 100 // Size of the entire terminal window. These need to be hard-coded here and in Viewport.h -#define COLS 100 -#define ROWS (31 + MESSAGE_LINES) +#define COLS 100 +#define ROWS (31 + MESSAGE_LINES) // Returns the sign of the input: // - if (x == 0) ===> returns 0 @@ -142,11 +143,9 @@ typedef struct pos { short y; } pos; -#define INVALID_POS ((pos) { .x = -1, .y = -1 }) +#define INVALID_POS ((pos){.x = -1, .y = -1}) -static inline boolean posEq(pos a, pos b) { - return a.x == b.x && a.y == b.y; -} +static inline boolean posEq(pos a, pos b) { return a.x == b.x && a.y == b.y; } // A location within the window. // Convert between `windowpos` and `pos` with `mapToWindow` and @@ -157,41 +156,40 @@ typedef struct windowpos { } windowpos; // Size of the portion of the terminal window devoted to displaying the dungeon: -#define DCOLS (COLS - STAT_BAR_WIDTH - 1) // n columns on the left for the sidebar; - // one column to separate the sidebar from the map. -#define DROWS (ROWS - MESSAGE_LINES - 2) // n lines at the top for messages; - // one line at the bottom for flavor text; - // another line at the bottom for the menu bar. +#define DCOLS \ + (COLS - STAT_BAR_WIDTH - 1) // n columns on the left for the sidebar; + // one column to separate the sidebar from the map. +#define DROWS \ + (ROWS - MESSAGE_LINES - 2) // n lines at the top for messages; + // one line at the bottom for flavor text; + // another line at the bottom for the menu bar. + +#define STAT_BAR_WIDTH 20 // number of characters in the stats bar to the left of the map -#define STAT_BAR_WIDTH 20 // number of characters in the stats bar to the left of the map +#define LOS_SLOPE_GRANULARITY \ + 32768 // how finely we divide up the squares when calculating slope; + // higher numbers mean fewer artifacts but more memory and processing +#define INTERFACE_OPACITY 95 -#define LOS_SLOPE_GRANULARITY 32768 // how finely we divide up the squares when calculating slope; - // higher numbers mean fewer artifacts but more memory and processing -#define INTERFACE_OPACITY 95 +#define LIGHT_SMOOTHING_THRESHOLD 150 // light components higher than this magnitude will be toned down a little -#define LIGHT_SMOOTHING_THRESHOLD 150 // light components higher than this magnitude will be toned down a little +#define MAX_BOLT_LENGTH DCOLS * 10 -#define MAX_BOLT_LENGTH DCOLS*10 +#define VISIBILITY_THRESHOLD 50 // how bright cumulative light has to be before the cell is marked visible -#define VISIBILITY_THRESHOLD 50 // how bright cumulative light has to be before the cell is marked visible +#define MACHINES_BUFFER_LENGTH 200 -#define MACHINES_BUFFER_LENGTH 200 - -#define INPUT_RECORD_BUFFER 1000 // how many bytes of input data to keep in memory before saving it to disk -#define DEFAULT_PLAYBACK_DELAY 50 +#define INPUT_RECORD_BUFFER 1000 // how many bytes of input data to keep in memory before saving it to disk +#define DEFAULT_PLAYBACK_DELAY 50 -#define HIGH_SCORES_COUNT 30 +#define HIGH_SCORES_COUNT 30 // color escapes -#define COLOR_ESCAPE 25 -#define COLOR_VALUE_INTERCEPT 25 +#define COLOR_ESCAPE 25 +#define COLOR_VALUE_INTERCEPT 25 // variants supported in this code base -enum gameVariant { - VARIANT_BROGUE, - VARIANT_RAPID_BROGUE, - NUMBER_VARIANTS -}; +enum gameVariant { VARIANT_BROGUE, VARIANT_RAPID_BROGUE, NUMBER_VARIANTS }; // display characters: @@ -348,13 +346,7 @@ enum eventTypes { NUMBER_OF_EVENT_TYPES, // unused }; -enum notificationEventTypes { - GAMEOVER_QUIT, - GAMEOVER_DEATH, - GAMEOVER_VICTORY, - GAMEOVER_SUPERVICTORY, - GAMEOVER_RECORDING -}; +enum notificationEventTypes { GAMEOVER_QUIT, GAMEOVER_DEATH, GAMEOVER_VICTORY, GAMEOVER_SUPERVICTORY, GAMEOVER_RECORDING }; typedef struct rogueEvent { enum eventTypes eventType; @@ -388,17 +380,17 @@ enum displayDetailValues { }; enum directions { - NO_DIRECTION = -1, + NO_DIRECTION = -1, // Cardinal directions; must be 0-3: - UP = 0, - DOWN = 1, - LEFT = 2, - RIGHT = 3, + UP = 0, + DOWN = 1, + LEFT = 2, + RIGHT = 3, // Secondary directions; must be 4-7: - UPLEFT = 4, - DOWNLEFT = 5, - UPRIGHT = 6, - DOWNRIGHT = 7, + UPLEFT = 4, + DOWNLEFT = 5, + UPRIGHT = 6, + DOWNRIGHT = 7, DIRECTION_COUNT = 8, }; @@ -410,7 +402,7 @@ enum textEntryTypes { TEXT_INPUT_TYPES, }; -#define NUMBER_DYNAMIC_COLORS 6 +#define NUMBER_DYNAMIC_COLORS 6 enum tileType { NOTHING = 0, @@ -718,23 +710,23 @@ enum lightType { NUMBER_LIGHT_KINDS }; -#define NUMBER_ITEM_CATEGORIES 13 +#define NUMBER_ITEM_CATEGORIES 13 // Item categories enum itemCategory { - FOOD = Fl(0), - WEAPON = Fl(1), - ARMOR = Fl(2), - POTION = Fl(3), - SCROLL = Fl(4), - STAFF = Fl(5), - WAND = Fl(6), - RING = Fl(7), - CHARM = Fl(8), - GOLD = Fl(9), - AMULET = Fl(10), - GEM = Fl(11), - KEY = Fl(12), + FOOD = Fl(0), + WEAPON = Fl(1), + ARMOR = Fl(2), + POTION = Fl(3), + SCROLL = Fl(4), + STAFF = Fl(5), + WAND = Fl(6), + RING = Fl(7), + CHARM = Fl(8), + GOLD = Fl(9), + AMULET = Fl(10), + GEM = Fl(11), + KEY = Fl(12), // Categories where the kinds have intrinsic magic polarity; i.e. each kind // has a certain polarity (with positive enchant) which doesn't depend on @@ -743,26 +735,17 @@ enum itemCategory { // kinds in these categories have neutral polarity. HAS_INTRINSIC_POLARITY = (POTION | SCROLL | RING | WAND | STAFF), - CAN_BE_DETECTED = (WEAPON | ARMOR | POTION | SCROLL | RING | CHARM | WAND | STAFF | AMULET), - CAN_BE_ENCHANTED = (WEAPON | ARMOR | RING | CHARM | WAND | STAFF), - PRENAMED_CATEGORY = (FOOD | GOLD | AMULET | GEM | KEY), - NEVER_IDENTIFIABLE = (FOOD | CHARM | GOLD | AMULET | GEM | KEY), - CAN_BE_SWAPPED = (WEAPON | ARMOR | STAFF | CHARM | RING), - ALL_ITEMS = (FOOD|POTION|WEAPON|ARMOR|STAFF|WAND|SCROLL|RING|CHARM|GOLD|AMULET|GEM|KEY), + CAN_BE_DETECTED = (WEAPON | ARMOR | POTION | SCROLL | RING | CHARM | WAND | STAFF | AMULET), + CAN_BE_ENCHANTED = (WEAPON | ARMOR | RING | CHARM | WAND | STAFF), + PRENAMED_CATEGORY = (FOOD | GOLD | AMULET | GEM | KEY), + NEVER_IDENTIFIABLE = (FOOD | CHARM | GOLD | AMULET | GEM | KEY), + CAN_BE_SWAPPED = (WEAPON | ARMOR | STAFF | CHARM | RING), + ALL_ITEMS = (FOOD | POTION | WEAPON | ARMOR | STAFF | WAND | SCROLL | RING | CHARM | GOLD | AMULET | GEM | KEY), }; -enum keyKind { - KEY_DOOR, - KEY_CAGE, - KEY_PORTAL, - NUMBER_KEY_TYPES -}; +enum keyKind { KEY_DOOR, KEY_CAGE, KEY_PORTAL, NUMBER_KEY_TYPES }; -enum foodKind { - RATION, - FRUIT, - NUMBER_FOOD_KINDS -}; +enum foodKind { RATION, FRUIT, NUMBER_FOOD_KINDS }; enum potionKind { POTION_LIFE, @@ -807,30 +790,9 @@ enum weaponKind { NUMBER_WEAPON_KINDS }; -enum weaponEnchants { - W_SPEED, - W_QUIETUS, - W_PARALYSIS, - W_MULTIPLICITY, - W_SLOWING, - W_CONFUSION, - W_FORCE, - W_SLAYING, - W_MERCY, - NUMBER_GOOD_WEAPON_ENCHANT_KINDS = W_MERCY, - W_PLENTY, - NUMBER_WEAPON_RUNIC_KINDS -}; +enum weaponEnchants { W_SPEED, W_QUIETUS, W_PARALYSIS, W_MULTIPLICITY, W_SLOWING, W_CONFUSION, W_FORCE, W_SLAYING, W_MERCY, NUMBER_GOOD_WEAPON_ENCHANT_KINDS = W_MERCY, W_PLENTY, NUMBER_WEAPON_RUNIC_KINDS }; -enum armorKind { - LEATHER_ARMOR, - SCALE_MAIL, - CHAIN_MAIL, - BANDED_MAIL, - SPLINT_MAIL, - PLATE_MAIL, - NUMBER_ARMOR_KINDS -}; +enum armorKind { LEATHER_ARMOR, SCALE_MAIL, CHAIN_MAIL, BANDED_MAIL, SPLINT_MAIL, PLATE_MAIL, NUMBER_ARMOR_KINDS }; enum armorEnchants { A_MULTIPLICITY, @@ -848,17 +810,7 @@ enum armorEnchants { NUMBER_ARMOR_ENCHANT_KINDS, }; -enum wandKind { - WAND_TELEPORT, - WAND_SLOW, - WAND_POLYMORPH, - WAND_NEGATION, - WAND_DOMINATION, - WAND_BECKONING, - WAND_PLENTY, - WAND_INVISIBILITY, - WAND_EMPOWERMENT -}; +enum wandKind { WAND_TELEPORT, WAND_SLOW, WAND_POLYMORPH, WAND_NEGATION, WAND_DOMINATION, WAND_BECKONING, WAND_PLENTY, WAND_INVISIBILITY, WAND_EMPOWERMENT }; enum staffKind { STAFF_LIGHTNING, @@ -911,32 +863,9 @@ enum boltType { BOLT_WHIP }; -enum ringKind { - RING_CLAIRVOYANCE, - RING_STEALTH, - RING_REGENERATION, - RING_TRANSFERENCE, - RING_LIGHT, - RING_AWARENESS, - RING_WISDOM, - RING_REAPING, - NUMBER_RING_KINDS -}; +enum ringKind { RING_CLAIRVOYANCE, RING_STEALTH, RING_REGENERATION, RING_TRANSFERENCE, RING_LIGHT, RING_AWARENESS, RING_WISDOM, RING_REAPING, NUMBER_RING_KINDS }; -enum charmKind { - CHARM_HEALTH, - CHARM_PROTECTION, - CHARM_HASTE, - CHARM_FIRE_IMMUNITY, - CHARM_INVISIBILITY, - CHARM_TELEPATHY, - CHARM_LEVITATION, - CHARM_SHATTERING, - CHARM_GUARDIAN, - CHARM_TELEPORTATION, - CHARM_RECHARGING, - CHARM_NEGATION -}; +enum charmKind { CHARM_HEALTH, CHARM_PROTECTION, CHARM_HASTE, CHARM_FIRE_IMMUNITY, CHARM_INVISIBILITY, CHARM_TELEPATHY, CHARM_LEVITATION, CHARM_SHATTERING, CHARM_GUARDIAN, CHARM_TELEPORTATION, CHARM_RECHARGING, CHARM_NEGATION }; enum scrollKind { SCROLL_ENCHANTING, @@ -960,7 +889,7 @@ typedef struct meteredItem { int numberSpawned; } meteredItem; -#define MAX_PACK_ITEMS 26 +#define MAX_PACK_ITEMS 26 enum monsterTypes { MK_YOU, @@ -1038,257 +967,238 @@ enum monsterTypes { NUMBER_MONSTER_KINDS }; -#define NUMBER_MUTATORS 8 +#define NUMBER_MUTATORS 8 -#define MONSTER_CLASS_COUNT 15 +#define MONSTER_CLASS_COUNT 15 // flavors -#define NUMBER_ITEM_TITLES 14 -#define NUMBER_ITEM_COLORS 21 -#define NUMBER_TITLE_PHONEMES 21 -#define NUMBER_ITEM_WOODS 21 -#define NUMBER_POTION_DESCRIPTIONS 18 -#define NUMBER_ITEM_METALS 12 -#define NUMBER_ITEM_GEMS 18 +#define NUMBER_ITEM_TITLES 14 +#define NUMBER_ITEM_COLORS 21 +#define NUMBER_TITLE_PHONEMES 21 +#define NUMBER_ITEM_WOODS 21 +#define NUMBER_POTION_DESCRIPTIONS 18 +#define NUMBER_ITEM_METALS 12 +#define NUMBER_ITEM_GEMS 18 // Dungeon flags enum tileFlags { - DISCOVERED = Fl(0), - VISIBLE = Fl(1), // cell has sufficient light and is in field of view, ready to draw. - HAS_PLAYER = Fl(2), - HAS_MONSTER = Fl(3), - HAS_DORMANT_MONSTER = Fl(4), // hidden monster on the square - HAS_ITEM = Fl(5), - IN_FIELD_OF_VIEW = Fl(6), // player has unobstructed line of sight whether or not there is enough light - WAS_VISIBLE = Fl(7), - HAS_STAIRS = Fl(8), - SEARCHED_FROM_HERE = Fl(9), // player already auto-searched here; can't auto-search here again - IS_IN_SHADOW = Fl(10), // so that a player gains an automatic stealth bonus - MAGIC_MAPPED = Fl(11), - ITEM_DETECTED = Fl(12), - CLAIRVOYANT_VISIBLE = Fl(13), - WAS_CLAIRVOYANT_VISIBLE = Fl(14), - CLAIRVOYANT_DARKENED = Fl(15), // magical blindness from a cursed ring of clairvoyance - CAUGHT_FIRE_THIS_TURN = Fl(16), // so that fire does not spread asymmetrically - PRESSURE_PLATE_DEPRESSED = Fl(17), // so that traps do not trigger repeatedly while you stand on them - STABLE_MEMORY = Fl(18), // redraws will be pulled from the memory array, not recalculated - KNOWN_TO_BE_TRAP_FREE = Fl(19), // keep track of where the player has stepped or watched monsters step as he knows no traps are there - IS_IN_PATH = Fl(20), // the yellow trail leading to the cursor - IN_LOOP = Fl(21), // this cell is part of a terrain loop - IS_CHOKEPOINT = Fl(22), // if this cell is blocked, part of the map will be rendered inaccessible - IS_GATE_SITE = Fl(23), // consider placing a locked door here - IS_IN_ROOM_MACHINE = Fl(24), - IS_IN_AREA_MACHINE = Fl(25), - IS_POWERED = Fl(26), // has been activated by machine power this turn (flag can probably be eliminated if needed) - IMPREGNABLE = Fl(27), // no tunneling allowed! - TERRAIN_COLORS_DANCING = Fl(28), // colors here will sparkle when the game is idle - TELEPATHIC_VISIBLE = Fl(29), // potions of telepathy let you see through other creatures' eyes - WAS_TELEPATHIC_VISIBLE = Fl(30), // potions of telepathy let you see through other creatures' eyes - - IS_IN_MACHINE = (IS_IN_ROOM_MACHINE | IS_IN_AREA_MACHINE), // sacred ground; don't generate items here, or teleport randomly to it - - PERMANENT_TILE_FLAGS = (DISCOVERED | MAGIC_MAPPED | ITEM_DETECTED | HAS_ITEM | HAS_DORMANT_MONSTER - | HAS_MONSTER | HAS_STAIRS | SEARCHED_FROM_HERE | PRESSURE_PLATE_DEPRESSED - | STABLE_MEMORY | KNOWN_TO_BE_TRAP_FREE | IN_LOOP + DISCOVERED = Fl(0), + VISIBLE = Fl(1), // cell has sufficient light and is in field of view, ready to draw. + HAS_PLAYER = Fl(2), + HAS_MONSTER = Fl(3), + HAS_DORMANT_MONSTER = Fl(4), // hidden monster on the square + HAS_ITEM = Fl(5), + IN_FIELD_OF_VIEW = Fl(6), // player has unobstructed line of sight whether or not there is enough light + WAS_VISIBLE = Fl(7), + HAS_STAIRS = Fl(8), + SEARCHED_FROM_HERE = Fl(9), // player already auto-searched here; can't auto-search here again + IS_IN_SHADOW = Fl(10), // so that a player gains an automatic stealth bonus + MAGIC_MAPPED = Fl(11), + ITEM_DETECTED = Fl(12), + CLAIRVOYANT_VISIBLE = Fl(13), + WAS_CLAIRVOYANT_VISIBLE = Fl(14), + CLAIRVOYANT_DARKENED = Fl(15), // magical blindness from a cursed ring of clairvoyance + CAUGHT_FIRE_THIS_TURN = Fl(16), // so that fire does not spread asymmetrically + PRESSURE_PLATE_DEPRESSED = Fl(17), // so that traps do not trigger repeatedly while you stand on them + STABLE_MEMORY = Fl(18), // redraws will be pulled from the memory array, not recalculated + KNOWN_TO_BE_TRAP_FREE = Fl(19), // keep track of where the player has stepped or watched monsters step as he knows no traps are there + IS_IN_PATH = Fl(20), // the yellow trail leading to the cursor + IN_LOOP = Fl(21), // this cell is part of a terrain loop + IS_CHOKEPOINT = Fl(22), // if this cell is blocked, part of the map will be rendered inaccessible + IS_GATE_SITE = Fl(23), // consider placing a locked door here + IS_IN_ROOM_MACHINE = Fl(24), + IS_IN_AREA_MACHINE = Fl(25), + IS_POWERED = Fl(26), // has been activated by machine power this turn (flag can probably be eliminated if needed) + IMPREGNABLE = Fl(27), // no tunneling allowed! + TERRAIN_COLORS_DANCING = Fl(28), // colors here will sparkle when the game is idle + TELEPATHIC_VISIBLE = Fl(29), // potions of telepathy let you see through other creatures' eyes + WAS_TELEPATHIC_VISIBLE = Fl(30), // potions of telepathy let you see through other creatures' eyes + + IS_IN_MACHINE = (IS_IN_ROOM_MACHINE | IS_IN_AREA_MACHINE), // sacred ground; don't generate items here, or teleport randomly to it + + PERMANENT_TILE_FLAGS = (DISCOVERED | MAGIC_MAPPED | ITEM_DETECTED | HAS_ITEM | HAS_DORMANT_MONSTER | HAS_MONSTER | HAS_STAIRS | SEARCHED_FROM_HERE | PRESSURE_PLATE_DEPRESSED | STABLE_MEMORY | KNOWN_TO_BE_TRAP_FREE | IN_LOOP | IS_CHOKEPOINT | IS_GATE_SITE | IS_IN_MACHINE | IMPREGNABLE), - ANY_KIND_OF_VISIBLE = (VISIBLE | CLAIRVOYANT_VISIBLE | TELEPATHIC_VISIBLE), + ANY_KIND_OF_VISIBLE = (VISIBLE | CLAIRVOYANT_VISIBLE | TELEPATHIC_VISIBLE), }; -#define TURNS_FOR_FULL_REGEN 300 -#define STOMACH_SIZE 2150 -#define HUNGER_THRESHOLD (STOMACH_SIZE - 1800) -#define WEAK_THRESHOLD 150 -#define FAINT_THRESHOLD 50 -#define MAX_EXP_LEVEL 20 -#define MAX_EXP 100000000L +#define TURNS_FOR_FULL_REGEN 300 +#define STOMACH_SIZE 2150 +#define HUNGER_THRESHOLD (STOMACH_SIZE - 1800) +#define WEAK_THRESHOLD 150 +#define FAINT_THRESHOLD 50 +#define MAX_EXP_LEVEL 20 +#define MAX_EXP 100000000L -#define XPXP_NEEDED_FOR_TELEPATHIC_BOND 1400 // XPXP required to enable telepathic awareness with the ally +#define XPXP_NEEDED_FOR_TELEPATHIC_BOND 1400 // XPXP required to enable telepathic awareness with the ally -#define ROOM_MIN_WIDTH 4 -#define ROOM_MAX_WIDTH 20 -#define ROOM_MIN_HEIGHT 3 -#define ROOM_MAX_HEIGHT 7 -#define HORIZONTAL_CORRIDOR_MIN_LENGTH 5 -#define HORIZONTAL_CORRIDOR_MAX_LENGTH 15 -#define VERTICAL_CORRIDOR_MIN_LENGTH 2 -#define VERTICAL_CORRIDOR_MAX_LENGTH 9 -#define CROSS_ROOM_MIN_WIDTH 3 -#define CROSS_ROOM_MAX_WIDTH 12 -#define CROSS_ROOM_MIN_HEIGHT 2 -#define CROSS_ROOM_MAX_HEIGHT 5 -#define MIN_SCALED_ROOM_DIMENSION 2 +#define ROOM_MIN_WIDTH 4 +#define ROOM_MAX_WIDTH 20 +#define ROOM_MIN_HEIGHT 3 +#define ROOM_MAX_HEIGHT 7 +#define HORIZONTAL_CORRIDOR_MIN_LENGTH 5 +#define HORIZONTAL_CORRIDOR_MAX_LENGTH 15 +#define VERTICAL_CORRIDOR_MIN_LENGTH 2 +#define VERTICAL_CORRIDOR_MAX_LENGTH 9 +#define CROSS_ROOM_MIN_WIDTH 3 +#define CROSS_ROOM_MAX_WIDTH 12 +#define CROSS_ROOM_MIN_HEIGHT 2 +#define CROSS_ROOM_MAX_HEIGHT 5 +#define MIN_SCALED_ROOM_DIMENSION 2 -#define ROOM_TYPE_COUNT 8 +#define ROOM_TYPE_COUNT 8 -#define CORRIDOR_WIDTH 1 +#define CORRIDOR_WIDTH 1 -#define WAYPOINT_SIGHT_RADIUS 10 -#define MAX_WAYPOINT_COUNT 40 +#define WAYPOINT_SIGHT_RADIUS 10 +#define MAX_WAYPOINT_COUNT 40 -#define MAX_ITEMS_IN_MONSTER_ITEMS_HOPPER 100 +#define MAX_ITEMS_IN_MONSTER_ITEMS_HOPPER 100 // Making these larger means cave generation will take more trials; set them too high and the program will hang. -#define CAVE_MIN_WIDTH 50 -#define CAVE_MIN_HEIGHT 20 +#define CAVE_MIN_WIDTH 50 +#define CAVE_MIN_HEIGHT 20 // Keyboard commands: -#define UP_KEY 'k' -#define DOWN_KEY 'j' -#define LEFT_KEY 'h' -#define RIGHT_KEY 'l' -#define UP_ARROW 63232 -#define LEFT_ARROW 63234 -#define DOWN_ARROW 63233 -#define RIGHT_ARROW 63235 -#define UPLEFT_KEY 'y' -#define UPRIGHT_KEY 'u' -#define DOWNLEFT_KEY 'b' -#define DOWNRIGHT_KEY 'n' -#define DESCEND_KEY '>' -#define ASCEND_KEY '<' -#define REST_KEY 'z' -#define AUTO_REST_KEY 'Z' -#define SEARCH_KEY 's' -#define INVENTORY_KEY 'i' -#define ACKNOWLEDGE_KEY ' ' -#define EQUIP_KEY 'e' -#define UNEQUIP_KEY 'r' -#define APPLY_KEY 'a' -#define THROW_KEY 't' -#define RETHROW_KEY 'T' -#define RELABEL_KEY 'R' -#define SWAP_KEY 'w' -#define TRUE_COLORS_KEY '\\' -#define STEALTH_RANGE_KEY ']' -#define DROP_KEY 'd' -#define CALL_KEY 'c' -#define QUIT_KEY 'Q' +#define UP_KEY 'k' +#define DOWN_KEY 'j' +#define LEFT_KEY 'h' +#define RIGHT_KEY 'l' +#define UP_ARROW 63232 +#define LEFT_ARROW 63234 +#define DOWN_ARROW 63233 +#define RIGHT_ARROW 63235 +#define UPLEFT_KEY 'y' +#define UPRIGHT_KEY 'u' +#define DOWNLEFT_KEY 'b' +#define DOWNRIGHT_KEY 'n' +#define DESCEND_KEY '>' +#define ASCEND_KEY '<' +#define REST_KEY 'z' +#define AUTO_REST_KEY 'Z' +#define SEARCH_KEY 's' +#define INVENTORY_KEY 'i' +#define ACKNOWLEDGE_KEY ' ' +#define EQUIP_KEY 'e' +#define UNEQUIP_KEY 'r' +#define APPLY_KEY 'a' +#define THROW_KEY 't' +#define RETHROW_KEY 'T' +#define RELABEL_KEY 'R' +#define SWAP_KEY 'w' +#define TRUE_COLORS_KEY '\\' +#define STEALTH_RANGE_KEY ']' +#define DROP_KEY 'd' +#define CALL_KEY 'c' +#define QUIT_KEY 'Q' #define MESSAGE_ARCHIVE_KEY 'M' -#define BROGUE_HELP_KEY '?' -#define DISCOVERIES_KEY 'D' +#define BROGUE_HELP_KEY '?' +#define DISCOVERIES_KEY 'D' #define CREATE_ITEM_MONSTER_KEY 'C' -#define EXPLORE_KEY 'x' -#define AUTOPLAY_KEY 'A' -#define SEED_KEY '~' -#define EASY_MODE_KEY '&' -#define ESCAPE_KEY '\033' -#define RETURN_KEY '\012' -#define DELETE_KEY '\177' -#define TAB_KEY '\t' -#define SHIFT_TAB_KEY 25 // Cocoa reports shift-tab this way for some reason. -#define PERIOD_KEY '.' -#define VIEW_RECORDING_KEY 'V' +#define EXPLORE_KEY 'x' +#define AUTOPLAY_KEY 'A' +#define SEED_KEY '~' +#define EASY_MODE_KEY '&' +#define ESCAPE_KEY '\033' +#define RETURN_KEY '\012' +#define DELETE_KEY '\177' +#define TAB_KEY '\t' +#define SHIFT_TAB_KEY 25 // Cocoa reports shift-tab this way for some reason. +#define PERIOD_KEY '.' +#define VIEW_RECORDING_KEY 'V' #define LOAD_SAVED_GAME_KEY 'O' -#define SAVE_GAME_KEY 'S' -#define NEW_GAME_KEY 'N' -#define GRAPHICS_KEY 'G' +#define SAVE_GAME_KEY 'S' +#define NEW_GAME_KEY 'N' +#define GRAPHICS_KEY 'G' #define SWITCH_TO_PLAYING_KEY 'P' -#define NUMPAD_0 48 -#define NUMPAD_1 49 -#define NUMPAD_2 50 -#define NUMPAD_3 51 -#define NUMPAD_4 52 -#define NUMPAD_5 53 -#define NUMPAD_6 54 -#define NUMPAD_7 55 -#define NUMPAD_8 56 -#define NUMPAD_9 57 -#define PAGE_UP_KEY 63276 -#define PAGE_DOWN_KEY 63277 -#define PRINTSCREEN_KEY '\054' - -#define UNKNOWN_KEY (128+19) - -#define min(x, y) (((x) < (y)) ? (x) : (y)) -#define max(x, y) (((x) > (y)) ? (x) : (y)) -#define clamp(x, low, hi) (min(hi, max(x, low))) // pins x to the [y, z] interval - -#define terrainFlags(x, y) (tileCatalog[pmap[x][y].layers[DUNGEON]].flags \ - | tileCatalog[pmap[x][y].layers[LIQUID]].flags \ - | tileCatalog[pmap[x][y].layers[SURFACE]].flags \ - | tileCatalog[pmap[x][y].layers[GAS]].flags) - -#define terrainMechFlags(x, y) (tileCatalog[pmap[x][y].layers[DUNGEON]].mechFlags \ - | tileCatalog[pmap[x][y].layers[LIQUID]].mechFlags \ - | tileCatalog[pmap[x][y].layers[SURFACE]].mechFlags \ - | tileCatalog[pmap[x][y].layers[GAS]].mechFlags) +#define NUMPAD_0 48 +#define NUMPAD_1 49 +#define NUMPAD_2 50 +#define NUMPAD_3 51 +#define NUMPAD_4 52 +#define NUMPAD_5 53 +#define NUMPAD_6 54 +#define NUMPAD_7 55 +#define NUMPAD_8 56 +#define NUMPAD_9 57 +#define PAGE_UP_KEY 63276 +#define PAGE_DOWN_KEY 63277 +#define PRINTSCREEN_KEY '\054' + +#define UNKNOWN_KEY (128 + 19) + +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#define max(x, y) (((x) > (y)) ? (x) : (y)) +#define clamp(x, low, hi) (min(hi, max(x, low))) // pins x to the [y, z] interval + +#define terrainFlags(x, y) (tileCatalog[pmap[x][y].layers[DUNGEON]].flags | tileCatalog[pmap[x][y].layers[LIQUID]].flags | tileCatalog[pmap[x][y].layers[SURFACE]].flags | tileCatalog[pmap[x][y].layers[GAS]].flags) + +#define terrainMechFlags(x, y) (tileCatalog[pmap[x][y].layers[DUNGEON]].mechFlags | tileCatalog[pmap[x][y].layers[LIQUID]].mechFlags | tileCatalog[pmap[x][y].layers[SURFACE]].mechFlags | tileCatalog[pmap[x][y].layers[GAS]].mechFlags) #ifdef BROGUE_ASSERTS boolean cellHasTerrainFlag(short x, short y, unsigned long flagMask); #else -#define cellHasTerrainFlag(x, y, flagMask) ((flagMask) & terrainFlags((x), (y)) ? true : false) +#define cellHasTerrainFlag(x, y, flagMask) ((flagMask)&terrainFlags((x), (y)) ? true : false) #endif -#define cellHasTMFlag(x, y, flagMask) ((flagMask) & terrainMechFlags((x), (y)) ? true : false) +#define cellHasTMFlag(x, y, flagMask) ((flagMask)&terrainMechFlags((x), (y)) ? true : false) -#define cellHasTerrainType(x, y, terrain) ((pmap[x][y].layers[DUNGEON] == (terrain) \ - || pmap[x][y].layers[LIQUID] == (terrain) \ - || pmap[x][y].layers[SURFACE] == (terrain) \ - || pmap[x][y].layers[GAS] == (terrain)) ? true : false) +#define cellHasTerrainType(x, y, terrain) ((pmap[x][y].layers[DUNGEON] == (terrain) || pmap[x][y].layers[LIQUID] == (terrain) || pmap[x][y].layers[SURFACE] == (terrain) || pmap[x][y].layers[GAS] == (terrain)) ? true : false) -#define cellHasKnownTerrainFlag(x, y, flagMask) ((flagMask) & pmap[(x)][(y)].rememberedTerrainFlags ? true : false) +#define cellHasKnownTerrainFlag(x, y, flagMask) ((flagMask)&pmap[(x)][(y)].rememberedTerrainFlags ? true : false) -#define cellIsPassableOrDoor(x, y) (!cellHasTerrainFlag((x), (y), T_PATHING_BLOCKER) \ - || (cellHasTMFlag((x), (y), (TM_IS_SECRET | TM_PROMOTES_WITH_KEY | TM_CONNECTS_LEVEL)) \ - && cellHasTerrainFlag((x), (y), T_OBSTRUCTS_PASSABILITY))) +#define cellIsPassableOrDoor(x, y) (!cellHasTerrainFlag((x), (y), T_PATHING_BLOCKER) || (cellHasTMFlag((x), (y), (TM_IS_SECRET | TM_PROMOTES_WITH_KEY | TM_CONNECTS_LEVEL)) && cellHasTerrainFlag((x), (y), T_OBSTRUCTS_PASSABILITY))) -#define coordinatesAreInMap(x, y) ((x) >= 0 && (x) < DCOLS && (y) >= 0 && (y) < DROWS) +#define coordinatesAreInMap(x, y) ((x) >= 0 && (x) < DCOLS && (y) >= 0 && (y) < DROWS) -inline static boolean isPosInMap(pos p) { - return p.x >= 0 && p.x < DCOLS && p.y >= 0 && p.y < DROWS; -} +inline static boolean isPosInMap(pos p) { return p.x >= 0 && p.x < DCOLS && p.y >= 0 && p.y < DROWS; } -inline static boolean locIsInWindow(windowpos w) { - return w.window_x >= 0 && w.window_x < COLS && w.window_y >= 0 && w.window_y < ROWS; -} +inline static boolean locIsInWindow(windowpos w) { return w.window_x >= 0 && w.window_x < COLS && w.window_y >= 0 && w.window_y < ROWS; } inline static pos windowToMap(windowpos w) { - return (pos) { + return (pos){ .x = w.window_x - STAT_BAR_WIDTH - 1, .y = w.window_y - MESSAGE_LINES, }; } inline static windowpos mapToWindow(pos p) { - return (windowpos) { + return (windowpos){ .window_x = p.x + STAT_BAR_WIDTH + 1, .window_y = p.y + MESSAGE_LINES, }; } // Prefer using `mapToWindow` to combine both coordinates together. -#define mapToWindowX(x) ((x) + STAT_BAR_WIDTH + 1) +#define mapToWindowX(x) ((x) + STAT_BAR_WIDTH + 1) // Prefer using `mapToWindow` to combine both coordinates together. -#define mapToWindowY(y) ((y) + MESSAGE_LINES) +#define mapToWindowY(y) ((y) + MESSAGE_LINES) // Prefer using `windowToMap` to combine both coordinates together. -#define windowToMapX(x) ((x) - STAT_BAR_WIDTH - 1) +#define windowToMapX(x) ((x)-STAT_BAR_WIDTH - 1) // Prefer using `windowToMap` to combine both coordinates together. -#define windowToMapY(y) ((y) - MESSAGE_LINES) +#define windowToMapY(y) ((y)-MESSAGE_LINES) -#define playerCanDirectlySee(x, y) (pmap[x][y].flags & VISIBLE) -#define playerCanSee(x, y) (pmap[x][y].flags & ANY_KIND_OF_VISIBLE) -#define playerCanSeeOrSense(x, y) ((pmap[x][y].flags & ANY_KIND_OF_VISIBLE) \ - || (rogue.playbackOmniscience \ - && (pmap[x][y].layers[DUNGEON] != GRANITE || (pmap[x][y].flags & DISCOVERED)))) +#define playerCanDirectlySee(x, y) (pmap[x][y].flags & VISIBLE) +#define playerCanSee(x, y) (pmap[x][y].flags & ANY_KIND_OF_VISIBLE) +#define playerCanSeeOrSense(x, y) ((pmap[x][y].flags & ANY_KIND_OF_VISIBLE) || (rogue.playbackOmniscience && (pmap[x][y].layers[DUNGEON] != GRANITE || (pmap[x][y].flags & DISCOVERED)))) -#define assureCosmeticRNG short oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; -#define restoreRNG rogue.RNG = oldRNG; +#define assureCosmeticRNG \ + short oldRNG = rogue.RNG; \ + rogue.RNG = RNG_COSMETIC; +#define restoreRNG rogue.RNG = oldRNG; -#define MIN_COLOR_DIFF 600 +#define MIN_COLOR_DIFF 600 // weighted sum of the squares of the component differences. Weights are according to color perception. -#define COLOR_DIFF(f, b) (((f).red - (b).red) * ((f).red - (b).red) * 0.2126 \ -+ ((f).green - (b).green) * ((f).green - (b).green) * 0.7152 \ -+ ((f).blue - (b).blue) * ((f).blue - (b).blue) * 0.0722) +#define COLOR_DIFF(f, b) (((f).red - (b).red) * ((f).red - (b).red) * 0.2126 + ((f).green - (b).green) * ((f).green - (b).green) * 0.7152 + ((f).blue - (b).blue) * ((f).blue - (b).blue) * 0.0722) // structs enum dungeonLayers { NO_LAYER = -1, - DUNGEON = 0, // dungeon-level tile (e.g. walls) - LIQUID, // liquid-level tile (e.g. lava) - GAS, // gas-level tile (e.g. fire, smoke, swamp gas) - SURFACE, // surface-level tile (e.g. grass) + DUNGEON = 0, // dungeon-level tile (e.g. walls) + LIQUID, // liquid-level tile (e.g. lava) + GAS, // gas-level tile (e.g. fire, smoke, swamp gas) + SURFACE, // surface-level tile (e.g. grass) NUMBER_TERRAIN_LAYERS }; @@ -1300,26 +1210,26 @@ typedef struct cellDisplayBuffer { char opacity; } cellDisplayBuffer; -typedef struct pcell { // permanent cell; have to remember this stuff to save levels - enum tileType layers[NUMBER_TERRAIN_LAYERS]; // terrain - unsigned long flags; // non-terrain cell flags - unsigned short volume; // quantity of gas in cell +typedef struct pcell { // permanent cell; have to remember this stuff to save levels + enum tileType layers[NUMBER_TERRAIN_LAYERS]; // terrain + unsigned long flags; // non-terrain cell flags + unsigned short volume; // quantity of gas in cell unsigned char machineNumber; - cellDisplayBuffer rememberedAppearance; // how the player remembers the cell to look - enum itemCategory rememberedItemCategory; // what category of item the player remembers lying there - short rememberedItemKind; // what kind of item the player remembers lying there - short rememberedItemQuantity; // how many of the item the player remembers lying there - short rememberedItemOriginDepth; // the origin depth of the item the player remembers lying there - enum tileType rememberedTerrain; // what the player remembers as the terrain (i.e. highest priority terrain upon last seeing) - unsigned long rememberedCellFlags; // map cell flags the player remembers from that spot - unsigned long rememberedTerrainFlags; // terrain flags the player remembers from that spot - unsigned long rememberedTMFlags; // TM flags the player remembers from that spot - short exposedToFire; // number of times the tile has been exposed to fire since the last environment update + cellDisplayBuffer rememberedAppearance; // how the player remembers the cell to look + enum itemCategory rememberedItemCategory; // what category of item the player remembers lying there + short rememberedItemKind; // what kind of item the player remembers lying there + short rememberedItemQuantity; // how many of the item the player remembers lying there + short rememberedItemOriginDepth; // the origin depth of the item the player remembers lying there + enum tileType rememberedTerrain; // what the player remembers as the terrain (i.e. highest priority terrain upon last seeing) + unsigned long rememberedCellFlags; // map cell flags the player remembers from that spot + unsigned long rememberedTerrainFlags; // terrain flags the player remembers from that spot + unsigned long rememberedTMFlags; // TM flags the player remembers from that spot + short exposedToFire; // number of times the tile has been exposed to fire since the last environment update } pcell; -typedef struct tcell { // transient cell; stuff we don't need to remember between levels - short light[3]; // RGB components of lighting - short oldLight[3]; // compare with subsequent lighting to determine whether to refresh cell +typedef struct tcell { // transient cell; stuff we don't need to remember between levels + short light[3]; // RGB components of lighting + short oldLight[3]; // compare with subsequent lighting to determine whether to refresh cell } tcell; typedef struct randomRange { @@ -1347,35 +1257,35 @@ typedef struct color { } color; enum itemFlags { - ITEM_IDENTIFIED = Fl(0), - ITEM_EQUIPPED = Fl(1), - ITEM_CURSED = Fl(2), - ITEM_PROTECTED = Fl(3), + ITEM_IDENTIFIED = Fl(0), + ITEM_EQUIPPED = Fl(1), + ITEM_CURSED = Fl(2), + ITEM_PROTECTED = Fl(3), // unused = Fl(4), - ITEM_RUNIC = Fl(5), - ITEM_RUNIC_HINTED = Fl(6), - ITEM_RUNIC_IDENTIFIED = Fl(7), - ITEM_CAN_BE_IDENTIFIED = Fl(8), - ITEM_PREPLACED = Fl(9), - ITEM_FLAMMABLE = Fl(10), - ITEM_MAGIC_DETECTED = Fl(11), - ITEM_MAX_CHARGES_KNOWN = Fl(12), - ITEM_IS_KEY = Fl(13), - - ITEM_ATTACKS_STAGGER = Fl(14), // mace, hammer - ITEM_ATTACKS_EXTEND = Fl(15), // whip - ITEM_ATTACKS_QUICKLY = Fl(16), // rapier - ITEM_ATTACKS_PENETRATE = Fl(17), // spear, pike - ITEM_ATTACKS_ALL_ADJACENT=Fl(18), // axe, war axe - ITEM_LUNGE_ATTACKS = Fl(19), // rapier + ITEM_RUNIC = Fl(5), + ITEM_RUNIC_HINTED = Fl(6), + ITEM_RUNIC_IDENTIFIED = Fl(7), + ITEM_CAN_BE_IDENTIFIED = Fl(8), + ITEM_PREPLACED = Fl(9), + ITEM_FLAMMABLE = Fl(10), + ITEM_MAGIC_DETECTED = Fl(11), + ITEM_MAX_CHARGES_KNOWN = Fl(12), + ITEM_IS_KEY = Fl(13), + + ITEM_ATTACKS_STAGGER = Fl(14), // mace, hammer + ITEM_ATTACKS_EXTEND = Fl(15), // whip + ITEM_ATTACKS_QUICKLY = Fl(16), // rapier + ITEM_ATTACKS_PENETRATE = Fl(17), // spear, pike + ITEM_ATTACKS_ALL_ADJACENT = Fl(18), // axe, war axe + ITEM_LUNGE_ATTACKS = Fl(19), // rapier ITEM_SNEAK_ATTACK_BONUS = Fl(20), // dagger - ITEM_PASS_ATTACKS = Fl(21), // flail + ITEM_PASS_ATTACKS = Fl(21), // flail - ITEM_KIND_AUTO_ID = Fl(22), // the item type will become known when the item is picked up. - ITEM_PLAYER_AVOIDS = Fl(23), // explore and travel will try to avoid picking the item up + ITEM_KIND_AUTO_ID = Fl(22), // the item type will become known when the item is picked up. + ITEM_PLAYER_AVOIDS = Fl(23), // explore and travel will try to avoid picking the item up }; -#define KEY_ID_MAXIMUM 20 +#define KEY_ID_MAXIMUM 20 typedef struct keyLocationProfile { short x; @@ -1407,7 +1317,7 @@ typedef struct item { keyLocationProfile keyLoc[KEY_ID_MAXIMUM]; short originDepth; unsigned long spawnTurnNumber; - unsigned long lastUsed[3]; // Absolute turns last applied + unsigned long lastUsed[3]; // Absolute turns last applied struct item *nextItem; } item; @@ -1789,25 +1699,26 @@ typedef struct lightSource { } lightSource; typedef struct flare { - const lightSource *light; // Flare light - short coeffChangeAmount; // The constant amount by which the coefficient changes per frame, e.g. -25 means it gets 25% dimmer per frame. - short coeffLimit; // Flare ends if the coefficient passes this percentage (whether going up or down). - pos loc; // Current flare location. - long coeff; // Current flare coefficient; always starts at 100. - unsigned long turnNumber; // So we can eliminate those that fired one or more turns ago. + const lightSource *light; // Flare light + short coeffChangeAmount; // The constant amount by which the coefficient changes per frame, e.g. -25 means it gets + // 25% dimmer per frame. + short coeffLimit; // Flare ends if the coefficient passes this percentage (whether going up or down). + pos loc; // Current flare location. + long coeff; // Current flare coefficient; always starts at 100. + unsigned long turnNumber; // So we can eliminate those that fired one or more turns ago. } flare; enum DFFlags { - DFF_EVACUATE_CREATURES_FIRST = Fl(0), // Creatures in the DF area get moved outside of it - DFF_SUBSEQ_EVERYWHERE = Fl(1), // Subsequent DF spawns in every cell that this DF spawns in, instead of only the origin - DFF_TREAT_AS_BLOCKING = Fl(2), // If filling the footprint of this DF with walls would disrupt level connectivity, then abort. - DFF_PERMIT_BLOCKING = Fl(3), // Generate this DF without regard to level connectivity. - DFF_ACTIVATE_DORMANT_MONSTER = Fl(4), // Dormant monsters on this tile will appear -- e.g. when a statue bursts to reveal a monster. - DFF_CLEAR_OTHER_TERRAIN = Fl(5), // Erase other terrain in the footprint of this DF. - DFF_BLOCKED_BY_OTHER_LAYERS = Fl(6), // Will not propagate into a cell if any layer in that cell has a superior priority. - DFF_SUPERPRIORITY = Fl(7), // Will overwrite terrain of a superior priority. - DFF_AGGRAVATES_MONSTERS = Fl(8), // Will act as though an aggravate monster scroll of effectRadius radius had been read at that point. - DFF_RESURRECT_ALLY = Fl(9), // Will bring back to life your most recently deceased ally. + DFF_EVACUATE_CREATURES_FIRST = Fl(0), // Creatures in the DF area get moved outside of it + DFF_SUBSEQ_EVERYWHERE = Fl(1), // Subsequent DF spawns in every cell that this DF spawns in, instead of only the origin + DFF_TREAT_AS_BLOCKING = Fl(2), // If filling the footprint of this DF with walls would disrupt level connectivity, then abort. + DFF_PERMIT_BLOCKING = Fl(3), // Generate this DF without regard to level connectivity. + DFF_ACTIVATE_DORMANT_MONSTER = Fl(4), // Dormant monsters on this tile will appear -- e.g. when a statue bursts to reveal a monster. + DFF_CLEAR_OTHER_TERRAIN = Fl(5), // Erase other terrain in the footprint of this DF. + DFF_BLOCKED_BY_OTHER_LAYERS = Fl(6), // Will not propagate into a cell if any layer in that cell has a superior priority. + DFF_SUPERPRIORITY = Fl(7), // Will overwrite terrain of a superior priority. + DFF_AGGRAVATES_MONSTERS = Fl(8), // Will act as though an aggravate monster scroll of effectRadius radius had been read at that point. + DFF_RESURRECT_ALLY = Fl(9), // Will bring back to life your most recently deceased ally. }; enum boltEffects { @@ -1836,22 +1747,22 @@ enum boltEffects { }; enum boltFlags { - BF_PASSES_THRU_CREATURES = Fl(0), // Bolt continues through creatures (e.g. lightning and tunneling) - BF_HALTS_BEFORE_OBSTRUCTION = Fl(1), // Bolt takes effect the space before it terminates (e.g. conjuration, obstruction, blinking) - BF_TARGET_ALLIES = Fl(2), // Staffs/wands/creatures that shoot this bolt will auto-target allies. - BF_TARGET_ENEMIES = Fl(3), // Staffs/wands/creatures that shoot this bolt will auto-target enemies. - BF_FIERY = Fl(4), // Bolt will light flammable terrain on fire as it passes, and will ignite monsters hit. - BF_NEVER_REFLECTS = Fl(6), // Bolt will never reflect (e.g. spiderweb, arrows). - BF_NOT_LEARNABLE = Fl(7), // This technique cannot be absorbed by empowered allies. - BF_NOT_NEGATABLE = Fl(8), // Won't be erased by negation. - BF_ELECTRIC = Fl(9), // Activates terrain that has TM_PROMOTES_ON_ELECTRICITY - BF_DISPLAY_CHAR_ALONG_LENGTH = Fl(10), // Display the character along the entire length of the bolt instead of just at the front. + BF_PASSES_THRU_CREATURES = Fl(0), // Bolt continues through creatures (e.g. lightning and tunneling) + BF_HALTS_BEFORE_OBSTRUCTION = Fl(1), // Bolt takes effect the space before it terminates (e.g. conjuration, obstruction, blinking) + BF_TARGET_ALLIES = Fl(2), // Staffs/wands/creatures that shoot this bolt will auto-target allies. + BF_TARGET_ENEMIES = Fl(3), // Staffs/wands/creatures that shoot this bolt will auto-target enemies. + BF_FIERY = Fl(4), // Bolt will light flammable terrain on fire as it passes, and will ignite monsters hit. + BF_NEVER_REFLECTS = Fl(6), // Bolt will never reflect (e.g. spiderweb, arrows). + BF_NOT_LEARNABLE = Fl(7), // This technique cannot be absorbed by empowered allies. + BF_NOT_NEGATABLE = Fl(8), // Won't be erased by negation. + BF_ELECTRIC = Fl(9), // Activates terrain that has TM_PROMOTES_ON_ELECTRICITY + BF_DISPLAY_CHAR_ALONG_LENGTH = Fl(10), // Display the character along the entire length of the bolt instead of just at the front. }; typedef struct bolt { char name[DCOLS]; char description[COLS]; - char abilityDescription[COLS*2]; + char abilityDescription[COLS * 2]; enum displayGlyph theChar; const color *foreColor; const color *backColor; @@ -1896,13 +1807,16 @@ typedef struct floorTileType { enum displayGlyph displayChar; const color *foreColor; const color *backColor; - short drawPriority; // priority (lower number means higher priority); governs drawing as well as tile replacement comparisons. - char chanceToIgnite; // chance to burn if a flame terrain is on one of the four cardinal neighbors - enum dungeonFeatureTypes fireType; // spawn this DF when the terrain ignites (or, if it's T_IS_DF_TRAP, when the pressure plate clicks) - enum dungeonFeatureTypes discoverType; // spawn this DF when successfully searched if T_IS_SECRET is set - enum dungeonFeatureTypes promoteType; // creates this dungeon spawn type when it promotes for some other reason (random promotion or promotion through machine activation) - short promoteChance; // percent chance per turn to spawn the promotion type; will also vanish upon doing so if T_VANISHES_UPON_PROMOTION is set - short glowLight; // if it glows, this is the ID of the light type + short drawPriority; // priority (lower number means higher priority); governs drawing as well as tile replacement + // comparisons. + char chanceToIgnite; // chance to burn if a flame terrain is on one of the four cardinal neighbors + enum dungeonFeatureTypes fireType; // spawn this DF when the terrain ignites (or, if it's T_IS_DF_TRAP, when the pressure plate clicks) + enum dungeonFeatureTypes discoverType; // spawn this DF when successfully searched if T_IS_SECRET is set + enum dungeonFeatureTypes promoteType; // creates this dungeon spawn type when it promotes for some other reason + // (random promotion or promotion through machine activation) + short promoteChance; // percent chance per turn to spawn the promotion type; will also vanish upon doing so if + // T_VANISHES_UPON_PROMOTION is set + short glowLight; // if it glows, this is the ID of the light type unsigned long flags; unsigned long mechFlags; char description[COLS]; @@ -1910,70 +1824,74 @@ typedef struct floorTileType { } floorTileType; enum terrainFlagCatalog { - T_OBSTRUCTS_PASSABILITY = Fl(0), // cannot be walked through - T_OBSTRUCTS_VISION = Fl(1), // blocks line of sight - T_OBSTRUCTS_ITEMS = Fl(2), // items can't be on this tile - T_OBSTRUCTS_SURFACE_EFFECTS = Fl(3), // grass, blood, etc. cannot exist on this tile - T_OBSTRUCTS_GAS = Fl(4), // blocks the permeation of gas - T_OBSTRUCTS_DIAGONAL_MOVEMENT = Fl(5), // can't step diagonally around this tile - T_SPONTANEOUSLY_IGNITES = Fl(6), // monsters avoid unless chasing player or immune to fire - T_AUTO_DESCENT = Fl(7), // automatically drops creatures down a depth level and does some damage (2d6) - T_LAVA_INSTA_DEATH = Fl(8), // kills any non-levitating non-fire-immune creature instantly - T_CAUSES_POISON = Fl(9), // any non-levitating creature gets 10 poison - T_IS_FLAMMABLE = Fl(10), // terrain can catch fire - T_IS_FIRE = Fl(11), // terrain is a type of fire; ignites neighboring flammable cells - T_ENTANGLES = Fl(12), // entangles players and monsters like a spiderweb - T_IS_DEEP_WATER = Fl(13), // steals items 50% of the time and moves them around randomly - T_CAUSES_DAMAGE = Fl(14), // anything on the tile takes max(1-2, 10%) damage per turn - T_CAUSES_NAUSEA = Fl(15), // any creature on the tile becomes nauseous - T_CAUSES_PARALYSIS = Fl(16), // anything caught on this tile is paralyzed - T_CAUSES_CONFUSION = Fl(17), // causes creatures on this tile to become confused - T_CAUSES_HEALING = Fl(18), // heals 20% max HP per turn for any player or non-inanimate monsters - T_IS_DF_TRAP = Fl(19), // spews gas of type specified in fireType when stepped on - T_CAUSES_EXPLOSIVE_DAMAGE = Fl(20), // is an explosion; deals higher of 15-20 or 50% damage instantly, but not again for five turns - T_SACRED = Fl(21), // monsters that aren't allies of the player will avoid stepping here - - T_OBSTRUCTS_SCENT = (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION | T_AUTO_DESCENT | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES), - T_PATHING_BLOCKER = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_IS_FIRE | T_SPONTANEOUSLY_IGNITES), - T_DIVIDES_LEVEL = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER), - T_LAKE_PATHING_BLOCKER = (T_AUTO_DESCENT | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES), - T_WAYPOINT_BLOCKER = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES), - T_MOVES_ITEMS = (T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH), - T_CAN_BE_BRIDGED = (T_AUTO_DESCENT), - T_OBSTRUCTS_EVERYTHING = (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION | T_OBSTRUCTS_ITEMS | T_OBSTRUCTS_GAS | T_OBSTRUCTS_SURFACE_EFFECTS | T_OBSTRUCTS_DIAGONAL_MOVEMENT), - T_HARMFUL_TERRAIN = (T_CAUSES_POISON | T_IS_FIRE | T_CAUSES_DAMAGE | T_CAUSES_PARALYSIS | T_CAUSES_CONFUSION | T_CAUSES_EXPLOSIVE_DAMAGE), - T_RESPIRATION_IMMUNITIES = (T_CAUSES_DAMAGE | T_CAUSES_CONFUSION | T_CAUSES_PARALYSIS | T_CAUSES_NAUSEA), + T_OBSTRUCTS_PASSABILITY = Fl(0), // cannot be walked through + T_OBSTRUCTS_VISION = Fl(1), // blocks line of sight + T_OBSTRUCTS_ITEMS = Fl(2), // items can't be on this tile + T_OBSTRUCTS_SURFACE_EFFECTS = Fl(3), // grass, blood, etc. cannot exist on this tile + T_OBSTRUCTS_GAS = Fl(4), // blocks the permeation of gas + T_OBSTRUCTS_DIAGONAL_MOVEMENT = Fl(5), // can't step diagonally around this tile + T_SPONTANEOUSLY_IGNITES = Fl(6), // monsters avoid unless chasing player or immune to fire + T_AUTO_DESCENT = Fl(7), // automatically drops creatures down a depth level and does some damage (2d6) + T_LAVA_INSTA_DEATH = Fl(8), // kills any non-levitating non-fire-immune creature instantly + T_CAUSES_POISON = Fl(9), // any non-levitating creature gets 10 poison + T_IS_FLAMMABLE = Fl(10), // terrain can catch fire + T_IS_FIRE = Fl(11), // terrain is a type of fire; ignites neighboring flammable cells + T_ENTANGLES = Fl(12), // entangles players and monsters like a spiderweb + T_IS_DEEP_WATER = Fl(13), // steals items 50% of the time and moves them around randomly + T_CAUSES_DAMAGE = Fl(14), // anything on the tile takes max(1-2, 10%) damage per turn + T_CAUSES_NAUSEA = Fl(15), // any creature on the tile becomes nauseous + T_CAUSES_PARALYSIS = Fl(16), // anything caught on this tile is paralyzed + T_CAUSES_CONFUSION = Fl(17), // causes creatures on this tile to become confused + T_CAUSES_HEALING = Fl(18), // heals 20% max HP per turn for any player or non-inanimate monsters + T_IS_DF_TRAP = Fl(19), // spews gas of type specified in fireType when stepped on + T_CAUSES_EXPLOSIVE_DAMAGE = Fl(20), // is an explosion; deals higher of 15-20 or 50% damage instantly, but not again for five turns + T_SACRED = Fl(21), // monsters that aren't allies of the player will avoid stepping here + + T_OBSTRUCTS_SCENT = (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION | T_AUTO_DESCENT | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES), + T_PATHING_BLOCKER = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_IS_FIRE | T_SPONTANEOUSLY_IGNITES), + T_DIVIDES_LEVEL = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER), + T_LAKE_PATHING_BLOCKER = (T_AUTO_DESCENT | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES), + T_WAYPOINT_BLOCKER = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES), + T_MOVES_ITEMS = (T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH), + T_CAN_BE_BRIDGED = (T_AUTO_DESCENT), + T_OBSTRUCTS_EVERYTHING = (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION | T_OBSTRUCTS_ITEMS | T_OBSTRUCTS_GAS | T_OBSTRUCTS_SURFACE_EFFECTS | T_OBSTRUCTS_DIAGONAL_MOVEMENT), + T_HARMFUL_TERRAIN = (T_CAUSES_POISON | T_IS_FIRE | T_CAUSES_DAMAGE | T_CAUSES_PARALYSIS | T_CAUSES_CONFUSION | T_CAUSES_EXPLOSIVE_DAMAGE), + T_RESPIRATION_IMMUNITIES = (T_CAUSES_DAMAGE | T_CAUSES_CONFUSION | T_CAUSES_PARALYSIS | T_CAUSES_NAUSEA), }; enum terrainMechanicalFlagCatalog { - TM_IS_SECRET = Fl(0), // successful search or being stepped on while visible transforms it into discoverType - TM_PROMOTES_WITH_KEY = Fl(1), // promotes if the key is present on the tile (in your pack, carried by monster, or lying on the ground) - TM_PROMOTES_WITHOUT_KEY = Fl(2), // promotes if the key is NOT present on the tile (in your pack, carried by monster, or lying on the ground) - TM_PROMOTES_ON_CREATURE = Fl(3), // promotes when a creature or player is on the tile (whether or not levitating) - TM_PROMOTES_ON_ITEM = Fl(4), // promotes when an item is on the tile - TM_PROMOTES_ON_ITEM_PICKUP = Fl(5), // promotes when an item is lifted from the tile (primarily for altars) - TM_PROMOTES_ON_PLAYER_ENTRY = Fl(6), // promotes when the player enters the tile (whether or not levitating) - TM_PROMOTES_ON_SACRIFICE_ENTRY = Fl(7), // promotes when the sacrifice target enters the tile (whether or not levitating) - TM_PROMOTES_ON_ELECTRICITY = Fl(8), // promotes when hit by a lightning bolt - TM_ALLOWS_SUBMERGING = Fl(9), // allows submersible monsters to submerge in this terrain - TM_IS_WIRED = Fl(10), // if wired, promotes when powered, and sends power when promoting - TM_IS_CIRCUIT_BREAKER = Fl(11), // prevents power from circulating in its machine - TM_GAS_DISSIPATES = Fl(12), // does not just hang in the air forever - TM_GAS_DISSIPATES_QUICKLY = Fl(13), // dissipates quickly - TM_EXTINGUISHES_FIRE = Fl(14), // extinguishes burning terrain or creatures - TM_VANISHES_UPON_PROMOTION = Fl(15), // vanishes when creating promotion dungeon feature, even if the replacement terrain priority doesn't require it - TM_REFLECTS_BOLTS = Fl(16), // magic bolts reflect off of its surface randomly (similar to pmap flag IMPREGNABLE) - TM_STAND_IN_TILE = Fl(17), // earthbound creatures will be said to stand "in" the tile, not on it - TM_LIST_IN_SIDEBAR = Fl(18), // terrain will be listed in the sidebar with a description of the terrain type - TM_VISUALLY_DISTINCT = Fl(19), // terrain will be color-adjusted if necessary so the character stands out from the background - TM_BRIGHT_MEMORY = Fl(20), // no blue fade when this tile is out of sight - TM_EXPLOSIVE_PROMOTE = Fl(21), // when burned, will promote to promoteType instead of burningType if surrounded by tiles with T_IS_FIRE or TM_EXPLOSIVE_PROMOTE - TM_CONNECTS_LEVEL = Fl(22), // will be treated as passable for purposes of calculating level connectedness, irrespective of other aspects of this terrain layer - TM_INTERRUPT_EXPLORATION_WHEN_SEEN = Fl(23), // will generate a message when discovered during exploration to interrupt exploration - TM_INVERT_WHEN_HIGHLIGHTED = Fl(24), // will flip fore and back colors when highlighted with pathing - TM_SWAP_ENCHANTS_ACTIVATION = Fl(25), // in machine, swap item enchantments when two suitable items are on this terrain, and activate the machine when that happens - - TM_PROMOTES_ON_STEP = (TM_PROMOTES_ON_CREATURE | TM_PROMOTES_ON_ITEM), + TM_IS_SECRET = Fl(0), // successful search or being stepped on while visible transforms it into discoverType + TM_PROMOTES_WITH_KEY = Fl(1), // promotes if the key is present on the tile (in your pack, carried by monster, or lying on the ground) + TM_PROMOTES_WITHOUT_KEY = Fl(2), // promotes if the key is NOT present on the tile (in your pack, carried by monster, or lying on the ground) + TM_PROMOTES_ON_CREATURE = Fl(3), // promotes when a creature or player is on the tile (whether or not levitating) + TM_PROMOTES_ON_ITEM = Fl(4), // promotes when an item is on the tile + TM_PROMOTES_ON_ITEM_PICKUP = Fl(5), // promotes when an item is lifted from the tile (primarily for altars) + TM_PROMOTES_ON_PLAYER_ENTRY = Fl(6), // promotes when the player enters the tile (whether or not levitating) + TM_PROMOTES_ON_SACRIFICE_ENTRY = Fl(7), // promotes when the sacrifice target enters the tile (whether or not levitating) + TM_PROMOTES_ON_ELECTRICITY = Fl(8), // promotes when hit by a lightning bolt + TM_ALLOWS_SUBMERGING = Fl(9), // allows submersible monsters to submerge in this terrain + TM_IS_WIRED = Fl(10), // if wired, promotes when powered, and sends power when promoting + TM_IS_CIRCUIT_BREAKER = Fl(11), // prevents power from circulating in its machine + TM_GAS_DISSIPATES = Fl(12), // does not just hang in the air forever + TM_GAS_DISSIPATES_QUICKLY = Fl(13), // dissipates quickly + TM_EXTINGUISHES_FIRE = Fl(14), // extinguishes burning terrain or creatures + TM_VANISHES_UPON_PROMOTION = Fl(15), // vanishes when creating promotion dungeon feature, even if the replacement + // terrain priority doesn't require it + TM_REFLECTS_BOLTS = Fl(16), // magic bolts reflect off of its surface randomly (similar to pmap flag IMPREGNABLE) + TM_STAND_IN_TILE = Fl(17), // earthbound creatures will be said to stand "in" the tile, not on it + TM_LIST_IN_SIDEBAR = Fl(18), // terrain will be listed in the sidebar with a description of the terrain type + TM_VISUALLY_DISTINCT = Fl(19), // terrain will be color-adjusted if necessary so the character stands out from the background + TM_BRIGHT_MEMORY = Fl(20), // no blue fade when this tile is out of sight + TM_EXPLOSIVE_PROMOTE = Fl(21), // when burned, will promote to promoteType instead of burningType if surrounded by + // tiles with T_IS_FIRE or TM_EXPLOSIVE_PROMOTE + TM_CONNECTS_LEVEL = Fl(22), // will be treated as passable for purposes of calculating level connectedness, + // irrespective of other aspects of this terrain layer + TM_INTERRUPT_EXPLORATION_WHEN_SEEN = Fl(23), // will generate a message when discovered during exploration to interrupt exploration + TM_INVERT_WHEN_HIGHLIGHTED = Fl(24), // will flip fore and back colors when highlighted with pathing + TM_SWAP_ENCHANTS_ACTIVATION = Fl(25), // in machine, swap item enchantments when two suitable items are on this + // terrain, and activate the machine when that happens + + TM_PROMOTES_ON_STEP = (TM_PROMOTES_ON_CREATURE | TM_PROMOTES_ON_ITEM), }; enum statusEffects { @@ -2008,134 +1926,126 @@ enum statusEffects { }; enum hordeFlags { - HORDE_DIES_ON_LEADER_DEATH = Fl(0), // if the leader dies, the horde will die instead of electing new leader - HORDE_IS_SUMMONED = Fl(1), // minions summoned when any creature is the same species as the leader and casts summon - HORDE_SUMMONED_AT_DISTANCE = Fl(2), // summons will appear across the level, and will naturally path back to the leader - HORDE_LEADER_CAPTIVE = Fl(3), // the leader is in chains and the followers are guards - HORDE_NO_PERIODIC_SPAWN = Fl(4), // can spawn only when the level begins -- not afterwards - HORDE_ALLIED_WITH_PLAYER = Fl(5), - - HORDE_MACHINE_BOSS = Fl(6), // used in machines for a boss challenge - HORDE_MACHINE_WATER_MONSTER = Fl(7), // used in machines where the room floods with shallow water - HORDE_MACHINE_CAPTIVE = Fl(8), // powerful captive monsters without any captors - HORDE_MACHINE_STATUE = Fl(9), // the kinds of monsters that make sense in a statue - HORDE_MACHINE_TURRET = Fl(10), // turrets, for hiding in walls - HORDE_MACHINE_MUD = Fl(11), // bog monsters, for hiding in mud - HORDE_MACHINE_KENNEL = Fl(12), // monsters that can appear in cages in kennels - HORDE_VAMPIRE_FODDER = Fl(13), // monsters that are prone to capture and farming by vampires - HORDE_MACHINE_LEGENDARY_ALLY = Fl(14), // legendary allies - HORDE_NEVER_OOD = Fl(15), // Horde cannot be generated out of depth - HORDE_MACHINE_THIEF = Fl(16), // monsters that can be generated in the key thief area machines - HORDE_MACHINE_GOBLIN_WARREN = Fl(17), // can spawn in goblin warrens - HORDE_SACRIFICE_TARGET = Fl(18), // can be the target of an assassination challenge; leader will get scary light. - - HORDE_MACHINE_ONLY = (HORDE_MACHINE_BOSS | HORDE_MACHINE_WATER_MONSTER - | HORDE_MACHINE_CAPTIVE | HORDE_MACHINE_STATUE - | HORDE_MACHINE_TURRET | HORDE_MACHINE_MUD - | HORDE_MACHINE_KENNEL | HORDE_VAMPIRE_FODDER - | HORDE_MACHINE_LEGENDARY_ALLY | HORDE_MACHINE_THIEF - | HORDE_MACHINE_GOBLIN_WARREN - | HORDE_SACRIFICE_TARGET), + HORDE_DIES_ON_LEADER_DEATH = Fl(0), // if the leader dies, the horde will die instead of electing new leader + HORDE_IS_SUMMONED = Fl(1), // minions summoned when any creature is the same species as the leader and casts summon + HORDE_SUMMONED_AT_DISTANCE = Fl(2), // summons will appear across the level, and will naturally path back to the leader + HORDE_LEADER_CAPTIVE = Fl(3), // the leader is in chains and the followers are guards + HORDE_NO_PERIODIC_SPAWN = Fl(4), // can spawn only when the level begins -- not afterwards + HORDE_ALLIED_WITH_PLAYER = Fl(5), + + HORDE_MACHINE_BOSS = Fl(6), // used in machines for a boss challenge + HORDE_MACHINE_WATER_MONSTER = Fl(7), // used in machines where the room floods with shallow water + HORDE_MACHINE_CAPTIVE = Fl(8), // powerful captive monsters without any captors + HORDE_MACHINE_STATUE = Fl(9), // the kinds of monsters that make sense in a statue + HORDE_MACHINE_TURRET = Fl(10), // turrets, for hiding in walls + HORDE_MACHINE_MUD = Fl(11), // bog monsters, for hiding in mud + HORDE_MACHINE_KENNEL = Fl(12), // monsters that can appear in cages in kennels + HORDE_VAMPIRE_FODDER = Fl(13), // monsters that are prone to capture and farming by vampires + HORDE_MACHINE_LEGENDARY_ALLY = Fl(14), // legendary allies + HORDE_NEVER_OOD = Fl(15), // Horde cannot be generated out of depth + HORDE_MACHINE_THIEF = Fl(16), // monsters that can be generated in the key thief area machines + HORDE_MACHINE_GOBLIN_WARREN = Fl(17), // can spawn in goblin warrens + HORDE_SACRIFICE_TARGET = Fl(18), // can be the target of an assassination challenge; leader will get scary light. + + HORDE_MACHINE_ONLY = (HORDE_MACHINE_BOSS | HORDE_MACHINE_WATER_MONSTER | HORDE_MACHINE_CAPTIVE | HORDE_MACHINE_STATUE | HORDE_MACHINE_TURRET | HORDE_MACHINE_MUD | HORDE_MACHINE_KENNEL | HORDE_VAMPIRE_FODDER + | HORDE_MACHINE_LEGENDARY_ALLY | HORDE_MACHINE_THIEF | HORDE_MACHINE_GOBLIN_WARREN | HORDE_SACRIFICE_TARGET), }; enum monsterBehaviorFlags { - MONST_INVISIBLE = Fl(0), // monster is invisible - MONST_INANIMATE = Fl(1), // monster has abbreviated stat bar display and is immune to many things - MONST_IMMOBILE = Fl(2), // monster won't move or perform melee attacks - MONST_CARRY_ITEM_100 = Fl(3), // monster carries an item 100% of the time - MONST_CARRY_ITEM_25 = Fl(4), // monster carries an item 25% of the time - MONST_ALWAYS_HUNTING = Fl(5), // monster is never asleep or in wandering mode - MONST_FLEES_NEAR_DEATH = Fl(6), // monster flees when under 25% health and re-engages when over 75% - MONST_ATTACKABLE_THRU_WALLS = Fl(7), // can be attacked when embedded in a wall - MONST_DEFEND_DEGRADE_WEAPON = Fl(8), // hitting the monster damages the weapon - MONST_IMMUNE_TO_WEAPONS = Fl(9), // weapons ineffective - MONST_FLIES = Fl(10), // permanent levitation - MONST_FLITS = Fl(11), // moves randomly a third of the time - MONST_IMMUNE_TO_FIRE = Fl(12), // won't burn, won't die in lava - MONST_CAST_SPELLS_SLOWLY = Fl(13), // takes twice the attack duration to cast a spell - MONST_IMMUNE_TO_WEBS = Fl(14), // monster passes freely through webs - MONST_REFLECT_4 = Fl(15), // monster reflects projectiles as though wearing +4 armor of reflection - MONST_NEVER_SLEEPS = Fl(16), // monster is always awake - MONST_FIERY = Fl(17), // monster carries an aura of flame (but no automatic fire light) - MONST_INVULNERABLE = Fl(18), // monster is immune to absolutely everything - MONST_IMMUNE_TO_WATER = Fl(19), // monster moves at full speed in deep water and (if player) doesn't drop items - MONST_RESTRICTED_TO_LIQUID = Fl(20), // monster can move only on tiles that allow submersion - MONST_SUBMERGES = Fl(21), // monster can submerge in appropriate terrain - MONST_MAINTAINS_DISTANCE = Fl(22), // monster tries to keep a distance of 3 tiles between it and player - MONST_WILL_NOT_USE_STAIRS = Fl(23), // monster won't chase the player between levels - MONST_DIES_IF_NEGATED = Fl(24), // monster will die if exposed to negation magic - MONST_MALE = Fl(25), // monster is male (or 50% likely to be male if also has MONST_FEMALE) - MONST_FEMALE = Fl(26), // monster is female (or 50% likely to be female if also has MONST_MALE) - MONST_NOT_LISTED_IN_SIDEBAR = Fl(27), // monster doesn't show up in the sidebar - MONST_GETS_TURN_ON_ACTIVATION = Fl(28), // monster never gets a turn, except when its machine is activated - MONST_ALWAYS_USE_ABILITY = Fl(29), // monster will never fail to use special ability if eligible (no random factor) - MONST_NO_POLYMORPH = Fl(30), // monster cannot result from a polymorph spell (liches, phoenixes and Warden of Yendor) - - NEGATABLE_TRAITS = (MONST_INVISIBLE | MONST_DEFEND_DEGRADE_WEAPON | MONST_IMMUNE_TO_WEAPONS | MONST_FLIES - | MONST_FLITS | MONST_IMMUNE_TO_FIRE | MONST_REFLECT_4 | MONST_FIERY | MONST_MAINTAINS_DISTANCE), - MONST_TURRET = (MONST_IMMUNE_TO_WEBS | MONST_NEVER_SLEEPS | MONST_IMMOBILE | MONST_INANIMATE | - MONST_ATTACKABLE_THRU_WALLS | MONST_WILL_NOT_USE_STAIRS), - LEARNABLE_BEHAVIORS = (MONST_INVISIBLE | MONST_FLIES | MONST_IMMUNE_TO_FIRE | MONST_REFLECT_4), - MONST_NEVER_VORPAL_ENEMY = (MONST_INANIMATE | MONST_INVULNERABLE | MONST_IMMOBILE | MONST_RESTRICTED_TO_LIQUID | MONST_GETS_TURN_ON_ACTIVATION | MONST_MAINTAINS_DISTANCE), - MONST_NEVER_MUTATED = (MONST_INVISIBLE | MONST_INANIMATE | MONST_IMMOBILE | MONST_INVULNERABLE), + MONST_INVISIBLE = Fl(0), // monster is invisible + MONST_INANIMATE = Fl(1), // monster has abbreviated stat bar display and is immune to many things + MONST_IMMOBILE = Fl(2), // monster won't move or perform melee attacks + MONST_CARRY_ITEM_100 = Fl(3), // monster carries an item 100% of the time + MONST_CARRY_ITEM_25 = Fl(4), // monster carries an item 25% of the time + MONST_ALWAYS_HUNTING = Fl(5), // monster is never asleep or in wandering mode + MONST_FLEES_NEAR_DEATH = Fl(6), // monster flees when under 25% health and re-engages when over 75% + MONST_ATTACKABLE_THRU_WALLS = Fl(7), // can be attacked when embedded in a wall + MONST_DEFEND_DEGRADE_WEAPON = Fl(8), // hitting the monster damages the weapon + MONST_IMMUNE_TO_WEAPONS = Fl(9), // weapons ineffective + MONST_FLIES = Fl(10), // permanent levitation + MONST_FLITS = Fl(11), // moves randomly a third of the time + MONST_IMMUNE_TO_FIRE = Fl(12), // won't burn, won't die in lava + MONST_CAST_SPELLS_SLOWLY = Fl(13), // takes twice the attack duration to cast a spell + MONST_IMMUNE_TO_WEBS = Fl(14), // monster passes freely through webs + MONST_REFLECT_4 = Fl(15), // monster reflects projectiles as though wearing +4 armor of reflection + MONST_NEVER_SLEEPS = Fl(16), // monster is always awake + MONST_FIERY = Fl(17), // monster carries an aura of flame (but no automatic fire light) + MONST_INVULNERABLE = Fl(18), // monster is immune to absolutely everything + MONST_IMMUNE_TO_WATER = Fl(19), // monster moves at full speed in deep water and (if player) doesn't drop items + MONST_RESTRICTED_TO_LIQUID = Fl(20), // monster can move only on tiles that allow submersion + MONST_SUBMERGES = Fl(21), // monster can submerge in appropriate terrain + MONST_MAINTAINS_DISTANCE = Fl(22), // monster tries to keep a distance of 3 tiles between it and player + MONST_WILL_NOT_USE_STAIRS = Fl(23), // monster won't chase the player between levels + MONST_DIES_IF_NEGATED = Fl(24), // monster will die if exposed to negation magic + MONST_MALE = Fl(25), // monster is male (or 50% likely to be male if also has MONST_FEMALE) + MONST_FEMALE = Fl(26), // monster is female (or 50% likely to be female if also has MONST_MALE) + MONST_NOT_LISTED_IN_SIDEBAR = Fl(27), // monster doesn't show up in the sidebar + MONST_GETS_TURN_ON_ACTIVATION = Fl(28), // monster never gets a turn, except when its machine is activated + MONST_ALWAYS_USE_ABILITY = Fl(29), // monster will never fail to use special ability if eligible (no random factor) + MONST_NO_POLYMORPH = Fl(30), // monster cannot result from a polymorph spell (liches, phoenixes and Warden of Yendor) + + NEGATABLE_TRAITS = (MONST_INVISIBLE | MONST_DEFEND_DEGRADE_WEAPON | MONST_IMMUNE_TO_WEAPONS | MONST_FLIES | MONST_FLITS | MONST_IMMUNE_TO_FIRE | MONST_REFLECT_4 | MONST_FIERY | MONST_MAINTAINS_DISTANCE), + MONST_TURRET = (MONST_IMMUNE_TO_WEBS | MONST_NEVER_SLEEPS | MONST_IMMOBILE | MONST_INANIMATE | MONST_ATTACKABLE_THRU_WALLS | MONST_WILL_NOT_USE_STAIRS), + LEARNABLE_BEHAVIORS = (MONST_INVISIBLE | MONST_FLIES | MONST_IMMUNE_TO_FIRE | MONST_REFLECT_4), + MONST_NEVER_VORPAL_ENEMY = (MONST_INANIMATE | MONST_INVULNERABLE | MONST_IMMOBILE | MONST_RESTRICTED_TO_LIQUID | MONST_GETS_TURN_ON_ACTIVATION | MONST_MAINTAINS_DISTANCE), + MONST_NEVER_MUTATED = (MONST_INVISIBLE | MONST_INANIMATE | MONST_IMMOBILE | MONST_INVULNERABLE), }; enum monsterAbilityFlags { - MA_HIT_HALLUCINATE = Fl(0), // monster can hit to cause hallucinations - MA_HIT_STEAL_FLEE = Fl(1), // monster can steal an item and then run away - MA_HIT_BURN = Fl(2), // monster can hit to set you on fire - MA_ENTER_SUMMONS = Fl(3), // monster will "become" its summoned leader, reappearing when that leader is defeated - MA_HIT_DEGRADE_ARMOR = Fl(4), // monster damages armor - MA_CAST_SUMMON = Fl(5), // requires that there be one or more summon hordes with this monster type as the leader - MA_SEIZES = Fl(6), // monster seizes enemies before attacking - MA_POISONS = Fl(7), // monster's damage is dealt in the form of poison - MA_DF_ON_DEATH = Fl(8), // monster spawns its DF when it dies - MA_CLONE_SELF_ON_DEFEND = Fl(9), // monster splits in two when struck - MA_KAMIKAZE = Fl(10), // monster dies instead of attacking - MA_TRANSFERENCE = Fl(11), // monster recovers 40 or 90% of the damage that it inflicts as health - MA_CAUSES_WEAKNESS = Fl(12), // monster attacks cause weakness status in target - MA_ATTACKS_PENETRATE = Fl(13), // monster attacks all adjacent enemies, like an axe - MA_ATTACKS_ALL_ADJACENT = Fl(14), // monster attacks penetrate one layer of enemies, like a spear - MA_ATTACKS_EXTEND = Fl(15), // monster attacks from a distance in a cardinal direction, like a whip - MA_ATTACKS_STAGGER = Fl(16), // monster attacks will push the player backward by one space if there is room - MA_AVOID_CORRIDORS = Fl(17), // monster will avoid corridors when hunting - - SPECIAL_HIT = (MA_HIT_HALLUCINATE | MA_HIT_STEAL_FLEE | MA_HIT_DEGRADE_ARMOR | MA_POISONS - | MA_TRANSFERENCE | MA_CAUSES_WEAKNESS | MA_HIT_BURN | MA_ATTACKS_STAGGER), - LEARNABLE_ABILITIES = (MA_TRANSFERENCE | MA_CAUSES_WEAKNESS), - - MA_NON_NEGATABLE_ABILITIES = (MA_ATTACKS_PENETRATE | MA_ATTACKS_ALL_ADJACENT | MA_ATTACKS_EXTEND | MA_ATTACKS_STAGGER), - MA_NEVER_VORPAL_ENEMY = (MA_KAMIKAZE), - MA_NEVER_MUTATED = (MA_KAMIKAZE), + MA_HIT_HALLUCINATE = Fl(0), // monster can hit to cause hallucinations + MA_HIT_STEAL_FLEE = Fl(1), // monster can steal an item and then run away + MA_HIT_BURN = Fl(2), // monster can hit to set you on fire + MA_ENTER_SUMMONS = Fl(3), // monster will "become" its summoned leader, reappearing when that leader is defeated + MA_HIT_DEGRADE_ARMOR = Fl(4), // monster damages armor + MA_CAST_SUMMON = Fl(5), // requires that there be one or more summon hordes with this monster type as the leader + MA_SEIZES = Fl(6), // monster seizes enemies before attacking + MA_POISONS = Fl(7), // monster's damage is dealt in the form of poison + MA_DF_ON_DEATH = Fl(8), // monster spawns its DF when it dies + MA_CLONE_SELF_ON_DEFEND = Fl(9), // monster splits in two when struck + MA_KAMIKAZE = Fl(10), // monster dies instead of attacking + MA_TRANSFERENCE = Fl(11), // monster recovers 40 or 90% of the damage that it inflicts as health + MA_CAUSES_WEAKNESS = Fl(12), // monster attacks cause weakness status in target + MA_ATTACKS_PENETRATE = Fl(13), // monster attacks all adjacent enemies, like an axe + MA_ATTACKS_ALL_ADJACENT = Fl(14), // monster attacks penetrate one layer of enemies, like a spear + MA_ATTACKS_EXTEND = Fl(15), // monster attacks from a distance in a cardinal direction, like a whip + MA_ATTACKS_STAGGER = Fl(16), // monster attacks will push the player backward by one space if there is room + MA_AVOID_CORRIDORS = Fl(17), // monster will avoid corridors when hunting + + SPECIAL_HIT = (MA_HIT_HALLUCINATE | MA_HIT_STEAL_FLEE | MA_HIT_DEGRADE_ARMOR | MA_POISONS | MA_TRANSFERENCE | MA_CAUSES_WEAKNESS | MA_HIT_BURN | MA_ATTACKS_STAGGER), + LEARNABLE_ABILITIES = (MA_TRANSFERENCE | MA_CAUSES_WEAKNESS), + + MA_NON_NEGATABLE_ABILITIES = (MA_ATTACKS_PENETRATE | MA_ATTACKS_ALL_ADJACENT | MA_ATTACKS_EXTEND | MA_ATTACKS_STAGGER), + MA_NEVER_VORPAL_ENEMY = (MA_KAMIKAZE), + MA_NEVER_MUTATED = (MA_KAMIKAZE), }; enum monsterBookkeepingFlags { - MB_WAS_VISIBLE = Fl(0), // monster was visible to player last turn - MB_TELEPATHICALLY_REVEALED = Fl(1), // player can magically see monster and adjacent cells - MB_PREPLACED = Fl(2), // monster dropped onto the level and requires post-processing - MB_APPROACHING_UPSTAIRS = Fl(3), // following the player up the stairs - MB_APPROACHING_DOWNSTAIRS = Fl(4), // following the player down the stairs - MB_APPROACHING_PIT = Fl(5), // following the player down a pit - MB_LEADER = Fl(6), // monster is the leader of a horde - MB_FOLLOWER = Fl(7), // monster is a member of a horde - MB_CAPTIVE = Fl(8), // monster is all tied up - MB_SEIZED = Fl(9), // monster is being held - MB_SEIZING = Fl(10), // monster is holding another creature immobile - MB_SUBMERGED = Fl(11), // monster is currently submerged and hence invisible until it attacks - MB_JUST_SUMMONED = Fl(12), // used to mark summons so they can be post-processed - MB_WILL_FLASH = Fl(13), // this monster will flash as soon as control is returned to the player - MB_BOUND_TO_LEADER = Fl(14), // monster will die if the leader dies or becomes separated from the leader - MB_MARKED_FOR_SACRIFICE = Fl(15), // scary glow, monster can be sacrificed in the appropriate machine - MB_ABSORBING = Fl(16), // currently learning a skill by absorbing an enemy corpse - MB_DOES_NOT_TRACK_LEADER = Fl(17), // monster will not follow its leader around - MB_IS_FALLING = Fl(18), // monster is plunging downward at the end of the turn - MB_IS_DYING = Fl(19), // monster is currently dying; the death is still being processed - MB_GIVEN_UP_ON_SCENT = Fl(20), // to help the monster remember that the scent map is a dead end - MB_IS_DORMANT = Fl(21), // lurking, waiting to burst out - MB_HAS_SOUL = Fl(22), // slaying the monster will count toward weapon auto-ID - MB_ALREADY_SEEN = Fl(23), // seeing this monster won't interrupt exploration - MB_ADMINISTRATIVE_DEATH = Fl(24), // like the `administrativeDeath` parameter to `killCreature` - MB_HAS_DIED = Fl(25) // monster has already been killed but not yet removed from `monsters` + MB_WAS_VISIBLE = Fl(0), // monster was visible to player last turn + MB_TELEPATHICALLY_REVEALED = Fl(1), // player can magically see monster and adjacent cells + MB_PREPLACED = Fl(2), // monster dropped onto the level and requires post-processing + MB_APPROACHING_UPSTAIRS = Fl(3), // following the player up the stairs + MB_APPROACHING_DOWNSTAIRS = Fl(4), // following the player down the stairs + MB_APPROACHING_PIT = Fl(5), // following the player down a pit + MB_LEADER = Fl(6), // monster is the leader of a horde + MB_FOLLOWER = Fl(7), // monster is a member of a horde + MB_CAPTIVE = Fl(8), // monster is all tied up + MB_SEIZED = Fl(9), // monster is being held + MB_SEIZING = Fl(10), // monster is holding another creature immobile + MB_SUBMERGED = Fl(11), // monster is currently submerged and hence invisible until it attacks + MB_JUST_SUMMONED = Fl(12), // used to mark summons so they can be post-processed + MB_WILL_FLASH = Fl(13), // this monster will flash as soon as control is returned to the player + MB_BOUND_TO_LEADER = Fl(14), // monster will die if the leader dies or becomes separated from the leader + MB_MARKED_FOR_SACRIFICE = Fl(15), // scary glow, monster can be sacrificed in the appropriate machine + MB_ABSORBING = Fl(16), // currently learning a skill by absorbing an enemy corpse + MB_DOES_NOT_TRACK_LEADER = Fl(17), // monster will not follow its leader around + MB_IS_FALLING = Fl(18), // monster is plunging downward at the end of the turn + MB_IS_DYING = Fl(19), // monster is currently dying; the death is still being processed + MB_GIVEN_UP_ON_SCENT = Fl(20), // to help the monster remember that the scent map is a dead end + MB_IS_DORMANT = Fl(21), // lurking, waiting to burst out + MB_HAS_SOUL = Fl(22), // slaying the monster will count toward weapon auto-ID + MB_ALREADY_SEEN = Fl(23), // seeing this monster won't interrupt exploration + MB_ADMINISTRATIVE_DEATH = Fl(24), // like the `administrativeDeath` parameter to `killCreature` + MB_HAS_DIED = Fl(25) // monster has already been killed but not yet removed from `monsters` }; // Defines all creatures, which include monsters and the player: @@ -2148,21 +2058,21 @@ typedef struct creatureType { short defense; short accuracy; randomRange damage; - long turnsBetweenRegen; // turns to wait before regaining 1 HP + long turnsBetweenRegen; // turns to wait before regaining 1 HP short movementSpeed; short attackSpeed; enum dungeonFeatureTypes bloodType; enum lightType intrinsicLightType; - boolean isLarge; // used for size of psychic emanation - short DFChance; // percent chance to spawn the dungeon feature per awake turn - enum dungeonFeatureTypes DFType; // kind of dungeon feature + boolean isLarge; // used for size of psychic emanation + short DFChance; // percent chance to spawn the dungeon feature per awake turn + enum dungeonFeatureTypes DFType; // kind of dungeon feature enum boltType bolts[20]; unsigned long flags; unsigned long abilityFlags; } creatureType; typedef struct monsterWords { - char flavorText[COLS*5]; + char flavorText[COLS * 5]; char absorbing[40]; char absorbStatus[40]; char attack[5][30]; @@ -2178,10 +2088,7 @@ enum creatureStates { MONSTER_ALLY, }; -enum creatureModes { - MODE_NORMAL, - MODE_PERM_FLEEING -}; +enum creatureModes { MODE_NORMAL, MODE_PERM_FLEEING }; typedef struct mutation { char title[100]; @@ -2233,51 +2140,51 @@ typedef struct creature { short depth; short currentHP; long turnsUntilRegen; - short regenPerTurn; // number of HP to regenerate every single turn - short weaknessAmount; // number of points of weakness that are inflicted by the weakness status - short poisonAmount; // number of points of damage per turn from poison - enum creatureStates creatureState; // current behavioral state - enum creatureModes creatureMode; // current behavioral mode (higher-level than state) + short regenPerTurn; // number of HP to regenerate every single turn + short weaknessAmount; // number of points of weakness that are inflicted by the weakness status + short poisonAmount; // number of points of damage per turn from poison + enum creatureStates creatureState; // current behavioral state + enum creatureModes creatureMode; // current behavioral mode (higher-level than state) - short mutationIndex; // what mutation the monster has (or -1 for none) - boolean wasNegated; // the monster has lost abilities due to negation + short mutationIndex; // what mutation the monster has (or -1 for none) + boolean wasNegated; // the monster has lost abilities due to negation // Waypoints: - short targetWaypointIndex; // the index number of the waypoint we're pathing toward + short targetWaypointIndex; // the index number of the waypoint we're pathing toward boolean waypointAlreadyVisited[MAX_WAYPOINT_COUNT]; // checklist of waypoints - pos lastSeenPlayerAt; // last location at which the monster hunted the player + pos lastSeenPlayerAt; // last location at which the monster hunted the player pos targetCorpseLoc; // location of the corpse that the monster is approaching to gain its abilities - char targetCorpseName[30]; // name of the deceased monster that we're approaching to gain its abilities - unsigned long absorptionFlags; // ability/behavior flags that the monster will gain when absorption is complete - boolean absorbBehavior; // above flag is behavior instead of ability (ignored if absorptionBolt is set) - short absorptionBolt; // bolt index that the monster will learn to cast when absorption is complete - short corpseAbsorptionCounter; // used to measure both the time until the monster stops being interested in the corpse, - // and, later, the time until the monster finishes absorbing the corpse. - short **mapToMe; // if a pack leader, this is a periodically updated pathing map to get to the leader - short **safetyMap; // fleeing monsters store their own safety map when out of player FOV to avoid omniscience - short ticksUntilTurn; // how long before the creature gets its next move + char targetCorpseName[30]; // name of the deceased monster that we're approaching to gain its abilities + unsigned long absorptionFlags; // ability/behavior flags that the monster will gain when absorption is complete + boolean absorbBehavior; // above flag is behavior instead of ability (ignored if absorptionBolt is set) + short absorptionBolt; // bolt index that the monster will learn to cast when absorption is complete + short corpseAbsorptionCounter; // used to measure both the time until the monster stops being interested in the + // corpse, and, later, the time until the monster finishes absorbing the corpse. + short **mapToMe; // if a pack leader, this is a periodically updated pathing map to get to the leader + short **safetyMap; // fleeing monsters store their own safety map when out of player FOV to avoid omniscience + short ticksUntilTurn; // how long before the creature gets its next move // Locally cached statistics that may be temporarily modified: short movementSpeed; short attackSpeed; - short previousHealthPoints; // remembers what your health proportion was at the start of the turn - short turnsSpentStationary; // how many (subjective) turns it's been since the creature moved between tiles - short flashStrength; // monster will flash soon; this indicates the percent strength of flash - color flashColor; // the color that the monster will flash + short previousHealthPoints; // remembers what your health proportion was at the start of the turn + short turnsSpentStationary; // how many (subjective) turns it's been since the creature moved between tiles + short flashStrength; // monster will flash soon; this indicates the percent strength of flash + color flashColor; // the color that the monster will flash short status[NUMBER_OF_STATUS_EFFECTS]; short maxStatus[NUMBER_OF_STATUS_EFFECTS]; // used to set the max point on the status bars unsigned long bookkeepingFlags; - short spawnDepth; // keep track of the depth of the machine to which they relate (for activation monsters) - short machineHome; // monsters that spawn in a machine keep track of the machine number here (for activation monsters) - short xpxp; // exploration experience (used to time telepathic bonding for allies) - short newPowerCount; // how many more times this monster can absorb a fallen monster - short totalPowerCount; // how many times has the monster been empowered? Used to recover abilities when negated. + short spawnDepth; // keep track of the depth of the machine to which they relate (for activation monsters) + short machineHome; // monsters that spawn in a machine keep track of the machine number here (for activation monsters) + short xpxp; // exploration experience (used to time telepathic bonding for allies) + short newPowerCount; // how many more times this monster can absorb a fallen monster + short totalPowerCount; // how many times has the monster been empowered? Used to recover abilities when negated. - struct creature *leader; // only if monster is a follower + struct creature *leader; // only if monster is a follower struct creature *carriedMonster; // when vampires turn into bats, one of the bats restores the vampire when it dies - struct item *carriedItem; // only used for monsters + struct item *carriedItem; // only used for monsters } creature; typedef struct creatureListNode { @@ -2287,7 +2194,7 @@ typedef struct creatureListNode { } creatureListNode; typedef struct creatureList { - creatureListNode* head; + creatureListNode *head; } creatureList; typedef struct creatureIterator { @@ -2322,112 +2229,107 @@ enum featTypes { FEAT_COUNT, }; -enum exitStatus { - EXIT_STATUS_SUCCESS, - EXIT_STATUS_FAILURE_RECORDING_WRONG_VERSION, - EXIT_STATUS_FAILURE_RECORDING_OOS, - EXIT_STATUS_FAILURE_PLATFORM_ERROR -}; +enum exitStatus { EXIT_STATUS_SUCCESS, EXIT_STATUS_FAILURE_RECORDING_WRONG_VERSION, EXIT_STATUS_FAILURE_RECORDING_OOS, EXIT_STATUS_FAILURE_PLATFORM_ERROR }; // Constants for the selected game variant, set in Globals{variant}.c // Many of these constants were migrated from #defines prior to variant support typedef struct gameConstants { - const int majorVersion; // variant major version x._._ - const int minorVersion; // variant minor version _.y._ - const int patchVersion; // variant patch version _._.z + const int majorVersion; // variant major version x._._ + const int minorVersion; // variant minor version _.y._ + const int patchVersion; // variant patch version _._.z - const char *variantName; // variant name in no-spaces, lower-case form (e.g. "brogue") + const char *variantName; // variant name in no-spaces, lower-case form (e.g. "brogue") - const char *versionString; // version string .. - const char *dungeonVersionString; // earliest version that has identical dungeons to this version - const char *patchVersionPattern; // scanf format string for patches that match this release - const char *recordingVersionString; // version string used in recordings / saves. Cannot be longer than 16 chars. + const char *versionString; // version string .. + const char *dungeonVersionString; // earliest version that has identical dungeons to this version + const char *patchVersionPattern; // scanf format string for patches that match this release + const char *recordingVersionString; // version string used in recordings / saves. Cannot be longer than 16 chars. - const int deepestLevel; // deepest level in the dungeon - const int amuletLevel; // level on which the amulet appears (used in signed arithmetic) + const int deepestLevel; // deepest level in the dungeon + const int amuletLevel; // level on which the amulet appears (used in signed arithmetic) - const int depthAccelerator; // factor for how fast depth-dependent features scale compared to usual 26-level dungeon - const int minimumLavaLevel; // how deep before lava can be generated - const int minimumBrimstoneLevel; // how deep before brimstone can be generated - const int mutationsOccurAboveLevel; // how deep before monster mutations can be generated + const int depthAccelerator; // factor for how fast depth-dependent features scale compared to usual 26-level dungeon + const int minimumLavaLevel; // how deep before lava can be generated + const int minimumBrimstoneLevel; // how deep before brimstone can be generated + const int mutationsOccurAboveLevel; // how deep before monster mutations can be generated - const int extraItemsPerLevel; // how many extra items generated per level above vanilla - const int goldAdjustmentStartDepth; // depth from which gold is adjusted based on generation so far + const int extraItemsPerLevel; // how many extra items generated per level above vanilla + const int goldAdjustmentStartDepth; // depth from which gold is adjusted based on generation so far - const int machinesPerLevelSuppressionMultiplier; // scale factor for limiting number of machines generated so far against depth + const int machinesPerLevelSuppressionMultiplier; // scale factor for limiting number of machines generated so far + // against depth const int machinesPerLevelSuppressionOffset; // offset for limiting number of machines generated so far against depth const int machinesPerLevelIncreaseFactor; // scale factor for increasing number of machines generated so far against depth const int maxLevelForBonusMachines; // deepest level that gets bonus machine generation chance - const int playerTransferenceRatio; // player transference heal is (enchant / gameConst->playerTransferenceRatio) - const int onHitHallucinateDuration; // duration of on-hit hallucination effect on player - const int onHitWeakenDuration; // duration of on-hit weaken effect - const int onHitMercyHealPercent; // percentage of damage healed on-hit by mercy weapon effect - - const int fallDamageMin; // minimum for fall damage range - const int fallDamageMax; // maximum for fall damage range - - const int weaponKillsToAutoID; // number of kills until unknown weapon is IDed - const int armorDelayToAutoID; // number of turns until unknown armor is IDed - const int ringDelayToAutoID; // number of turns until unknown ring is IDed - - const int numberAutogenerators; // size of autoGeneratorCatalog table - const int numberBoltKinds; // size of boltKinds table - const int numberBlueprints; // size of blueprintCatalog table - const int numberHordes; // size of the horde table - - const int numberMeteredItems; // size of the metered items table - const int numberCharmKinds; // size of the charms table - const int numberPotionKinds; // size of the potion table - const int numberGoodPotionKinds; // number of good potions in the game (ordered first in the table) - const int numberScrollKinds; // size of the scroll table - const int numberGoodScrollKinds; // number of good scrolls in the game (ordered first in the table) - const int numberWandKinds; // size of the wands table - const int numberGoodWandKinds; // number of good wands in the game (ordered first in the table) - - const int mainMenuTitleHeight; // height of the title screen in characters - const int mainMenuTitleWidth; // width of the title screen in characters + const int playerTransferenceRatio; // player transference heal is (enchant / gameConst->playerTransferenceRatio) + const int onHitHallucinateDuration; // duration of on-hit hallucination effect on player + const int onHitWeakenDuration; // duration of on-hit weaken effect + const int onHitMercyHealPercent; // percentage of damage healed on-hit by mercy weapon effect + + const int fallDamageMin; // minimum for fall damage range + const int fallDamageMax; // maximum for fall damage range + + const int weaponKillsToAutoID; // number of kills until unknown weapon is IDed + const int armorDelayToAutoID; // number of turns until unknown armor is IDed + const int ringDelayToAutoID; // number of turns until unknown ring is IDed + + const int numberAutogenerators; // size of autoGeneratorCatalog table + const int numberBoltKinds; // size of boltKinds table + const int numberBlueprints; // size of blueprintCatalog table + const int numberHordes; // size of the horde table + + const int numberMeteredItems; // size of the metered items table + const int numberCharmKinds; // size of the charms table + const int numberPotionKinds; // size of the potion table + const int numberGoodPotionKinds; // number of good potions in the game (ordered first in the table) + const int numberScrollKinds; // size of the scroll table + const int numberGoodScrollKinds; // number of good scrolls in the game (ordered first in the table) + const int numberWandKinds; // size of the wands table + const int numberGoodWandKinds; // number of good wands in the game (ordered first in the table) + + const int mainMenuTitleHeight; // height of the title screen in characters + const int mainMenuTitleWidth; // width of the title screen in characters } gameConstants; - // these are basically global variables pertaining to the game state and player's unique variables: typedef struct playerCharacter { - boolean wizard; // in wizard mode + boolean wizard; // in wizard mode - short depthLevel; // which dungeon level are we on + short depthLevel; // which dungeon level are we on short deepestLevel; - boolean disturbed; // player should stop auto-acting - boolean gameInProgress; // the game is in progress (the player has not died, won or quit yet) - boolean gameHasEnded; // stop everything and go to death screen - boolean highScoreSaved; // so that it saves the high score only once - boolean blockCombatText; // busy auto-fighting - boolean autoPlayingLevel; // seriously, don't interrupt - boolean automationActive; // cut some corners during redraws to speed things up - boolean justRested; // previous turn was a rest -- used in stealth - boolean justSearched; // previous turn was a search -- used in manual searches - boolean cautiousMode; // used to prevent careless deaths caused by holding down a key - boolean receivedLevitationWarning; // only warn you once when you're hovering dangerously over liquid - boolean updatedSafetyMapThisTurn; // so it's updated no more than once per turn - boolean updatedAllySafetyMapThisTurn; // so it's updated no more than once per turn - boolean updatedMapToSafeTerrainThisTurn;// so it's updated no more than once per turn - boolean updatedMapToShoreThisTurn; // so it's updated no more than once per turn - boolean easyMode; // enables easy mode - boolean inWater; // helps with the blue water filter effect - boolean heardCombatThisTurn; // so you get only one "you hear combat in the distance" per turn - boolean creaturesWillFlashThisTurn; // there are creatures out there that need to flash before the turn ends - boolean staleLoopMap; // recalculate the loop map at the end of the turn - boolean alreadyFell; // so the player can fall only one depth per turn - boolean eligibleToUseStairs; // so the player uses stairs only when he steps onto them - boolean trueColorMode; // whether lighting effects are disabled - boolean displayStealthRangeMode; // whether your stealth range is displayed - boolean quit; // to skip the typical end-game theatrics when the player quits - uint64_t seed; // the master seed for generating the entire dungeon - short RNG; // which RNG are we currently using? - unsigned long gold; // how much gold we have - unsigned long goldGenerated; // how much gold has been generated on the levels, not counting gold held by monsters + boolean disturbed; // player should stop auto-acting + boolean gameInProgress; // the game is in progress (the player has not died, won or quit yet) + boolean gameHasEnded; // stop everything and go to death screen + boolean highScoreSaved; // so that it saves the high score only once + boolean blockCombatText; // busy auto-fighting + boolean autoPlayingLevel; // seriously, don't interrupt + boolean automationActive; // cut some corners during redraws to speed things up + boolean justRested; // previous turn was a rest -- used in stealth + boolean justSearched; // previous turn was a search -- used in manual searches + boolean cautiousMode; // used to prevent careless deaths caused by holding down a key + boolean receivedLevitationWarning; // only warn you once when you're hovering dangerously over liquid + boolean updatedSafetyMapThisTurn; // so it's updated no more than once per turn + boolean updatedAllySafetyMapThisTurn; // so it's updated no more than once per turn + boolean updatedMapToSafeTerrainThisTurn; // so it's updated no more than once per turn + boolean updatedMapToShoreThisTurn; // so it's updated no more than once per turn + boolean easyMode; // enables easy mode + boolean inWater; // helps with the blue water filter effect + boolean heardCombatThisTurn; // so you get only one "you hear combat in the distance" per turn + boolean creaturesWillFlashThisTurn; // there are creatures out there that need to flash before the turn ends + boolean staleLoopMap; // recalculate the loop map at the end of the turn + boolean alreadyFell; // so the player can fall only one depth per turn + boolean eligibleToUseStairs; // so the player uses stairs only when he steps onto them + boolean trueColorMode; // whether lighting effects are disabled + boolean displayStealthRangeMode; // whether your stealth range is displayed + boolean quit; // to skip the typical end-game theatrics when the player quits + uint64_t seed; // the master seed for generating the entire dungeon + short RNG; // which RNG are we currently using? + unsigned long gold; // how much gold we have + unsigned long goldGenerated; // how much gold has been generated on the levels, not counting gold held by monsters short strength; - unsigned short monsterSpawnFuse; // how much longer till a random monster spawns + unsigned short monsterSpawnFuse; // how much longer till a random monster spawns item *weapon; item *armor; @@ -2444,52 +2346,52 @@ typedef struct playerCharacter { lightSource minersLight; fixpt minersLightRadius; - short ticksTillUpdateEnvironment; // so that some periodic things happen in objective time - unsigned short scentTurnNumber; // helps make scent-casting work - unsigned long playerTurnNumber; // number of input turns in recording. Does not increment during paralysis. - unsigned long absoluteTurnNumber; // number of turns since the beginning of time. Always increments. - signed long milliseconds; // milliseconds since launch, to decide whether to engage cautious mode - short xpxpThisTurn; // how many squares the player explored this turn - short stealthRange; // distance from which monsters will notice you + short ticksTillUpdateEnvironment; // so that some periodic things happen in objective time + unsigned short scentTurnNumber; // helps make scent-casting work + unsigned long playerTurnNumber; // number of input turns in recording. Does not increment during paralysis. + unsigned long absoluteTurnNumber; // number of turns since the beginning of time. Always increments. + signed long milliseconds; // milliseconds since launch, to decide whether to engage cautious mode + short xpxpThisTurn; // how many squares the player explored this turn + short stealthRange; // distance from which monsters will notice you - short previousPoisonPercent; // and your poison proportion, to display percentage alerts for each. + short previousPoisonPercent; // and your poison proportion, to display percentage alerts for each. - pos upLoc; // upstairs location this level - pos downLoc; // downstairs location this level + pos upLoc; // upstairs location this level + pos downLoc; // downstairs location this level - pos cursorLoc; // used for the return key functionality - creature *lastTarget; // to keep track of the last monster the player has thrown at or zapped + pos cursorLoc; // used for the return key functionality + creature *lastTarget; // to keep track of the last monster the player has thrown at or zapped item *lastItemThrown; - short rewardRoomsGenerated; // to meter the number of reward machines - short machineNumber; // so each machine on a level gets a unique number - pos sidebarLocationList[ROWS*2]; // to keep track of which location each line of the sidebar references + short rewardRoomsGenerated; // to meter the number of reward machines + short machineNumber; // so each machine on a level gets a unique number + pos sidebarLocationList[ROWS * 2]; // to keep track of which location each line of the sidebar references // maps - short **mapToShore; // how many steps to get back to shore - short **mapToSafeTerrain; // so monsters can get to safety + short **mapToShore; // how many steps to get back to shore + short **mapToSafeTerrain; // so monsters can get to safety // recording info - boolean recording; // whether we are recording the game - boolean playbackMode; // whether we're viewing a recording instead of playing - unsigned short patchVersion; // what patch version of the game this was recorded on - char versionString[16]; // the version string saved into the recording file - unsigned long currentTurnNumber; // how many turns have elapsed - unsigned long howManyTurns; // how many turns are in this recording - short howManyDepthChanges; // how many times the player changes depths - short playbackDelayPerTurn; // base playback speed; modified per turn by events - short playbackDelayThisTurn; // playback speed as modified + boolean recording; // whether we are recording the game + boolean playbackMode; // whether we're viewing a recording instead of playing + unsigned short patchVersion; // what patch version of the game this was recorded on + char versionString[16]; // the version string saved into the recording file + unsigned long currentTurnNumber; // how many turns have elapsed + unsigned long howManyTurns; // how many turns are in this recording + short howManyDepthChanges; // how many times the player changes depths + short playbackDelayPerTurn; // base playback speed; modified per turn by events + short playbackDelayThisTurn; // playback speed as modified boolean playbackPaused; - boolean playbackFastForward; // for loading saved games and such -- disables drawing and prevents pauses - boolean playbackOOS; // playback out of sync -- no unpausing allowed - boolean playbackOmniscience; // whether to reveal all the map during playback - boolean playbackBetweenTurns; // i.e. waiting for a top-level input -- iff, permit playback commands - unsigned long nextAnnotationTurn; // the turn number during which to display the next annotation - char nextAnnotation[5000]; // the next annotation + boolean playbackFastForward; // for loading saved games and such -- disables drawing and prevents pauses + boolean playbackOOS; // playback out of sync -- no unpausing allowed + boolean playbackOmniscience; // whether to reveal all the map during playback + boolean playbackBetweenTurns; // i.e. waiting for a top-level input -- iff, permit playback commands + unsigned long nextAnnotationTurn; // the turn number during which to display the next annotation + char nextAnnotation[5000]; // the next annotation unsigned long locationInAnnotationFile; // how far we've read in the annotations file - int gameExitStatusCode; // exit status code indicating if brogue exited successfully or with an error + int gameExitStatusCode; // exit status code indicating if brogue exited successfully or with an error // metered items - long long foodSpawned; // amount of nutrition units spawned so far this game + long long foodSpawned; // amount of nutrition units spawned so far this game meteredItem *meteredItems; // ring bonuses: @@ -2540,37 +2442,39 @@ typedef struct levelData { } levelData; enum machineFeatureFlags { - MF_GENERATE_ITEM = Fl(0), // feature entails generating an item (overridden if the machine is adopting an item) - MF_OUTSOURCE_ITEM_TO_MACHINE = Fl(1), // item must be adopted by another machine - MF_BUILD_VESTIBULE = Fl(2), // call this at the origin of a door room to create a new door guard machine there - MF_ADOPT_ITEM = Fl(3), // this feature will take the adopted item (be it from another machine or a previous feature) - MF_NO_THROWING_WEAPONS = Fl(4), // the generated item cannot be a throwing weapon - MF_GENERATE_HORDE = Fl(5), // generate a monster horde that has all of the horde flags - MF_BUILD_AT_ORIGIN = Fl(6), // generate this feature at the room entrance + MF_GENERATE_ITEM = Fl(0), // feature entails generating an item (overridden if the machine is adopting an item) + MF_OUTSOURCE_ITEM_TO_MACHINE = Fl(1), // item must be adopted by another machine + MF_BUILD_VESTIBULE = Fl(2), // call this at the origin of a door room to create a new door guard machine there + MF_ADOPT_ITEM = Fl(3), // this feature will take the adopted item (be it from another machine or a previous feature) + MF_NO_THROWING_WEAPONS = Fl(4), // the generated item cannot be a throwing weapon + MF_GENERATE_HORDE = Fl(5), // generate a monster horde that has all of the horde flags + MF_BUILD_AT_ORIGIN = Fl(6), // generate this feature at the room entrance // unused = Fl(7), // - MF_PERMIT_BLOCKING = Fl(8), // permit the feature to block the map's passability (e.g. to add a locked door) - MF_TREAT_AS_BLOCKING = Fl(9), // treat this terrain as though it blocks, for purposes of deciding whether it can be placed there - MF_NEAR_ORIGIN = Fl(10), // feature must spawn in the rough quarter of tiles closest to the origin - MF_FAR_FROM_ORIGIN = Fl(11), // feature must spawn in the rough quarter of tiles farthest from the origin - MF_MONSTER_TAKE_ITEM = Fl(12), // the item associated with this feature (including if adopted) will be in possession of the horde leader that's generated - MF_MONSTER_SLEEPING = Fl(13), // the monsters should be asleep when generated - MF_MONSTER_FLEEING = Fl(14), // the monsters should be permanently fleeing when generated - MF_EVERYWHERE = Fl(15), // generate the feature on every tile of the machine (e.g. carpeting) - MF_ALTERNATIVE = Fl(16), // build only one feature that has this flag per machine; the rest are skipped - MF_ALTERNATIVE_2 = Fl(17), // same as MF_ALTERNATIVE, but provides for a second set of alternatives of which only one will be chosen - MF_REQUIRE_GOOD_RUNIC = Fl(18), // generated item must be uncursed runic - MF_MONSTERS_DORMANT = Fl(19), // monsters are dormant, and appear when a dungeon feature with DFF_ACTIVATE_DORMANT_MONSTER spawns on their tile + MF_PERMIT_BLOCKING = Fl(8), // permit the feature to block the map's passability (e.g. to add a locked door) + MF_TREAT_AS_BLOCKING = Fl(9), // treat this terrain as though it blocks, for purposes of deciding whether it can be placed there + MF_NEAR_ORIGIN = Fl(10), // feature must spawn in the rough quarter of tiles closest to the origin + MF_FAR_FROM_ORIGIN = Fl(11), // feature must spawn in the rough quarter of tiles farthest from the origin + MF_MONSTER_TAKE_ITEM = Fl(12), // the item associated with this feature (including if adopted) will be in possession + // of the horde leader that's generated + MF_MONSTER_SLEEPING = Fl(13), // the monsters should be asleep when generated + MF_MONSTER_FLEEING = Fl(14), // the monsters should be permanently fleeing when generated + MF_EVERYWHERE = Fl(15), // generate the feature on every tile of the machine (e.g. carpeting) + MF_ALTERNATIVE = Fl(16), // build only one feature that has this flag per machine; the rest are skipped + MF_ALTERNATIVE_2 = Fl(17), // same as MF_ALTERNATIVE, but provides for a second set of alternatives of which only one will be chosen + MF_REQUIRE_GOOD_RUNIC = Fl(18), // generated item must be uncursed runic + MF_MONSTERS_DORMANT = Fl(19), // monsters are dormant, and appear when a dungeon feature with + // DFF_ACTIVATE_DORMANT_MONSTER spawns on their tile // unused = Fl(20), // - MF_BUILD_IN_WALLS = Fl(21), // build in an impassable tile that is adjacent to the interior - MF_BUILD_ANYWHERE_ON_LEVEL = Fl(22), // build anywhere on the level that is not inside the machine - MF_REPEAT_UNTIL_NO_PROGRESS = Fl(23), // keep trying to build this feature set until no changes are made - MF_IMPREGNABLE = Fl(24), // this feature's location will be immune to tunneling - MF_IN_VIEW_OF_ORIGIN = Fl(25), // this feature must be in view of the origin - MF_IN_PASSABLE_VIEW_OF_ORIGIN = Fl(26), // this feature must be in view of the origin, where "view" is blocked by pathing blockers - MF_NOT_IN_HALLWAY = Fl(27), // the feature location must have a passableArcCount of <= 1 - MF_NOT_ON_LEVEL_PERIMETER = Fl(28), // don't build it in the outermost walls of the level - MF_SKELETON_KEY = Fl(29), // if a key is generated or adopted by this feature, it will open all locks in this machine. - MF_KEY_DISPOSABLE = Fl(30), // if a key is generated or adopted, it will self-destruct after being used at this current location. + MF_BUILD_IN_WALLS = Fl(21), // build in an impassable tile that is adjacent to the interior + MF_BUILD_ANYWHERE_ON_LEVEL = Fl(22), // build anywhere on the level that is not inside the machine + MF_REPEAT_UNTIL_NO_PROGRESS = Fl(23), // keep trying to build this feature set until no changes are made + MF_IMPREGNABLE = Fl(24), // this feature's location will be immune to tunneling + MF_IN_VIEW_OF_ORIGIN = Fl(25), // this feature must be in view of the origin + MF_IN_PASSABLE_VIEW_OF_ORIGIN = Fl(26), // this feature must be in view of the origin, where "view" is blocked by pathing blockers + MF_NOT_IN_HALLWAY = Fl(27), // the feature location must have a passableArcCount of <= 1 + MF_NOT_ON_LEVEL_PERIMETER = Fl(28), // don't build it in the outermost walls of the level + MF_SKELETON_KEY = Fl(29), // if a key is generated or adopted by this feature, it will open all locks in this machine. + MF_KEY_DISPOSABLE = Fl(30), // if a key is generated or adopted, it will self-destruct after being used at this current location. }; typedef struct machineFeature { @@ -2579,47 +2483,49 @@ typedef struct machineFeature { enum tileType terrain; // generate this terrain tile at the feature location (0 for none) enum dungeonLayers layer; // generate the terrain tile in this layer - short instanceCountRange[2]; // generate this range of instances of this feature - short minimumInstanceCount; // abort if fewer than this + short instanceCountRange[2]; // generate this range of instances of this feature + short minimumInstanceCount; // abort if fewer than this // items: these will be ignored if the feature is adopting an item - short itemCategory; // generate this category of item (or -1 for random) - short itemKind; // generate this kind of item (or -1 for random) + short itemCategory; // generate this category of item (or -1 for random) + short itemKind; // generate this kind of item (or -1 for random) - short monsterID; // generate a monster of this kind if MF_GENERATE_MONSTER is set + short monsterID; // generate a monster of this kind if MF_GENERATE_MONSTER is set - short personalSpace; // subsequent features must be generated more than this many tiles away from this feature - unsigned long hordeFlags; // choose a monster horde based on this - unsigned long itemFlags; // assign these flags to the item - unsigned long flags; // feature flags + short personalSpace; // subsequent features must be generated more than this many tiles away from this feature + unsigned long hordeFlags; // choose a monster horde based on this + unsigned long itemFlags; // assign these flags to the item + unsigned long flags; // feature flags } machineFeature; enum blueprintFlags { - BP_ADOPT_ITEM = Fl(0), // the machine must adopt an item (e.g. a door key) - BP_VESTIBULE = Fl(1), // spawns in a doorway (location must be given) and expands outward, to guard the room - BP_PURGE_PATHING_BLOCKERS = Fl(2), // clean out traps and other T_PATHING_BLOCKERs - BP_PURGE_INTERIOR = Fl(3), // clean out all of the terrain in the interior before generating the machine - BP_PURGE_LIQUIDS = Fl(4), // clean out all of the liquids in the interior before generating the machine - BP_SURROUND_WITH_WALLS = Fl(5), // fill in any impassable gaps in the perimeter (e.g. water, lava, brimstone, traps) with wall - BP_IMPREGNABLE = Fl(6), // impassable perimeter and interior tiles are locked; tunneling bolts will bounce off harmlessly - BP_REWARD = Fl(7), // metered reward machines - BP_OPEN_INTERIOR = Fl(8), // clear out walls in the interior, widen the interior until convex or bumps into surrounding areas - BP_MAXIMIZE_INTERIOR = Fl(9), // same as BP_OPEN_INTERIOR but expands the room as far as it can go, potentially surrounding the whole level. - BP_ROOM = Fl(10), // spawns in a dead-end room that is dominated by a chokepoint of the given size (as opposed to a random place of the given size) - BP_TREAT_AS_BLOCKING = Fl(11), // abort the machine if, were it filled with wall tiles, it would disrupt the level connectivity - BP_REQUIRE_BLOCKING = Fl(12), // abort the machine unless, were it filled with wall tiles, it would disrupt the level connectivity - BP_NO_INTERIOR_FLAG = Fl(13), // don't flag the area as being part of a machine - BP_REDESIGN_INTERIOR = Fl(14), // nuke and pave -- delete all terrain in the interior and build entirely new rooms within the bounds + BP_ADOPT_ITEM = Fl(0), // the machine must adopt an item (e.g. a door key) + BP_VESTIBULE = Fl(1), // spawns in a doorway (location must be given) and expands outward, to guard the room + BP_PURGE_PATHING_BLOCKERS = Fl(2), // clean out traps and other T_PATHING_BLOCKERs + BP_PURGE_INTERIOR = Fl(3), // clean out all of the terrain in the interior before generating the machine + BP_PURGE_LIQUIDS = Fl(4), // clean out all of the liquids in the interior before generating the machine + BP_SURROUND_WITH_WALLS = Fl(5), // fill in any impassable gaps in the perimeter (e.g. water, lava, brimstone, traps) with wall + BP_IMPREGNABLE = Fl(6), // impassable perimeter and interior tiles are locked; tunneling bolts will bounce off harmlessly + BP_REWARD = Fl(7), // metered reward machines + BP_OPEN_INTERIOR = Fl(8), // clear out walls in the interior, widen the interior until convex or bumps into surrounding areas + BP_MAXIMIZE_INTERIOR = Fl(9), // same as BP_OPEN_INTERIOR but expands the room as far as it can go, potentially + // surrounding the whole level. + BP_ROOM = Fl(10), // spawns in a dead-end room that is dominated by a chokepoint of the given size (as opposed to a + // random place of the given size) + BP_TREAT_AS_BLOCKING = Fl(11), // abort the machine if, were it filled with wall tiles, it would disrupt the level connectivity + BP_REQUIRE_BLOCKING = Fl(12), // abort the machine unless, were it filled with wall tiles, it would disrupt the level connectivity + BP_NO_INTERIOR_FLAG = Fl(13), // don't flag the area as being part of a machine + BP_REDESIGN_INTERIOR = Fl(14), // nuke and pave -- delete all terrain in the interior and build entirely new rooms within the bounds }; typedef struct blueprint { - short depthRange[2]; // machine must be built between these dungeon depths - short roomSize[2]; // machine must be generated in a room of this size - short frequency; // frequency (number of tickets this blueprint enters in the blueprint selection raffle) - short featureCount; // how many different types of features follow (max of 20) - short dungeonProfileType; // if BP_REDESIGN_INTERIOR is set, which dungeon profile do we use? - unsigned long flags; // blueprint flags - machineFeature feature[20]; // the features themselves + short depthRange[2]; // machine must be built between these dungeon depths + short roomSize[2]; // machine must be generated in a room of this size + short frequency; // frequency (number of tickets this blueprint enters in the blueprint selection raffle) + short featureCount; // how many different types of features follow (max of 20) + short dungeonProfileType; // if BP_REDESIGN_INTERIOR is set, which dungeon profile do we use? + unsigned long flags; // blueprint flags + machineFeature feature[20]; // the features themselves } blueprint; enum machineTypes { @@ -2721,7 +2627,7 @@ typedef struct autoGenerator { short maxDepth; short frequency; short minNumberIntercept; // actually intercept * 100 - short minNumberSlope; // actually slope * 100 + short minNumberSlope; // actually slope * 100 short maxNumber; } autoGenerator; @@ -2731,20 +2637,20 @@ typedef struct feat { boolean initialValue; } feat; -#define PDS_FORBIDDEN -1 +#define PDS_FORBIDDEN -1 #define PDS_OBSTRUCTION -2 #define PDS_CELL(map, x, y) ((map)->links + ((x) + DCOLS * (y))) typedef struct brogueButton { - char text[COLS*3]; // button label; can include color escapes - short x; // button's leftmost cell will be drawn at (x, y) + char text[COLS * 3]; // button label; can include color escapes + short x; // button's leftmost cell will be drawn at (x, y) short y; - signed long hotkey[10]; // up to 10 hotkeys to trigger the button - color buttonColor; // background of the button; further gradient-ized when displayed - short opacity; // further reduced by 50% if not enabled - enum displayGlyph symbol[COLS]; // Automatically replace the nth asterisk in the button label text with - // the nth character supplied here, if one is given. - // (Primarily to display magic character and item symbols in the inventory display.) + signed long hotkey[10]; // up to 10 hotkeys to trigger the button + color buttonColor; // background of the button; further gradient-ized when displayed + short opacity; // further reduced by 50% if not enabled + enum displayGlyph symbol[COLS]; // Automatically replace the nth asterisk in the button label text with + // the nth character supplied here, if one is given. + // (Primarily to display magic character and item symbols in the inventory display.) unsigned long flags; } brogueButton; @@ -2755,12 +2661,12 @@ enum buttonDrawStates { }; enum BUTTON_FLAGS { - B_DRAW = Fl(0), - B_ENABLED = Fl(1), - B_GRADIENT = Fl(2), - B_HOVER_ENABLED = Fl(3), - B_WIDE_CLICK_AREA = Fl(4), - B_KEYPRESS_HIGHLIGHT = Fl(5), + B_DRAW = Fl(0), + B_ENABLED = Fl(1), + B_GRADIENT = Fl(2), + B_HOVER_ENABLED = Fl(3), + B_WIDE_CLICK_AREA = Fl(4), + B_KEYPRESS_HIGHLIGHT = Fl(5), }; typedef struct buttonState { @@ -2787,15 +2693,15 @@ typedef struct buttonState { } buttonState; enum messageFlags { - REQUIRE_ACKNOWLEDGMENT = Fl(0), - REFRESH_SIDEBAR = Fl(1), - FOLDABLE = Fl(2), + REQUIRE_ACKNOWLEDGMENT = Fl(0), + REFRESH_SIDEBAR = Fl(1), + FOLDABLE = Fl(2), }; typedef struct archivedMessage { - char message[COLS*2]; - unsigned char count; // how many times this message appears - unsigned long turn; // player turn of the first occurrence + char message[COLS * 2]; + unsigned char count; // how many times this message appears + unsigned long turn; // player turn of the first occurrence unsigned long flags; } archivedMessage; @@ -2808,645 +2714,541 @@ extern enum graphicsModes graphicsMode; extern "C" { #endif - // Utilities.c - String functions - boolean endswith(const char *str, const char *ending); - void append(char *str, char *ending, int bufsize); - - int rogueMain(); - void printBrogueVersion(); - void executeEvent(rogueEvent *theEvent); - boolean fileExists(const char *pathname); - boolean chooseFile(char *path, char *prompt, char *defaultName, char *suffix); - boolean openFile(const char *path); - void initializeGameVariant(); - void initializeRogue(uint64_t seed); - void gameOver(char *killedBy, boolean useCustomPhrasing); - void victory(boolean superVictory); - void initializeDynamicColors(); - void enableEasyMode(); - boolean tryParseUint64(char *str, uint64_t *num); - uint64_t rand_64bits(); - long rand_range(long lowerBound, long upperBound); - uint64_t seedRandomGenerator(uint64_t seed); - short randClumpedRange(short lowerBound, short upperBound, short clumpFactor); - short randClump(randomRange theRange); - boolean rand_percent(short percent); - void shuffleList(short *list, short listLength); - void fillSequentialList(short *list, short listLength); - fixpt fp_round(fixpt x); - fixpt fp_pow(fixpt base, int expn); - fixpt fp_sqrt(fixpt val); - short unflag(unsigned long flag); - void considerCautiousMode(); - void refreshScreen(); - void displayLevel(); - void storeColorComponents(char components[3], const color *theColor); - boolean separateColors(color *fore, const color *back); - void bakeColor(color *theColor); - void shuffleTerrainColors(short percentOfCells, boolean refreshCells); - void normColor(color *baseColor, const short aggregateMultiplier, const short colorTranslation); - void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *returnForeColor, color *returnBackColor); - void logBuffer(char array[DCOLS][DROWS]); - //void logBuffer(short **array); - boolean search(short searchStrength); - boolean proposeOrConfirmLocation(short x, short y, char *failureMessage); - boolean useStairs(short stairDirection); - short passableArcCount(short x, short y); - void analyzeMap(boolean calculateChokeMap); - boolean buildAMachine(enum machineTypes bp, - short originX, short originY, - unsigned long requiredMachineFlags, - item *adoptiveItem, - item *parentSpawnedItems[50], - creature *parentSpawnedMonsters[50]); - void attachRooms(short **grid, const dungeonProfile *theDP, short attempts, short maxRoomCount); - void digDungeon(); - void updateMapToShore(); - short levelIsDisconnectedWithBlockingMap(char blockingMap[DCOLS][DROWS], boolean countRegionSize); - void resetDFMessageEligibility(); - boolean fillSpawnMap(enum dungeonLayers layer, - enum tileType surfaceTileType, - char spawnMap[DCOLS][DROWS], - boolean blockedByOtherLayers, - boolean refresh, - boolean superpriority); - boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refreshCell, boolean abortIfBlocking); - void restoreMonster(creature *monst, short **mapToStairs, short **mapToPit); - void restoreItem(item *theItem); - void refreshWaypoint(short wpIndex); - void setUpWaypoints(); - void zeroOutGrid(char grid[DCOLS][DROWS]); - short oppositeDirection(short theDir); - - void plotChar(enum displayGlyph inputChar, - short xLoc, short yLoc, - short backRed, short backGreen, short backBlue, - short foreRed, short foreGreen, short foreBlue); - boolean pauseForMilliseconds(short milliseconds); - boolean isApplicationActive(); - void nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance); - void notifyEvent(short eventId, int data1, int data2, const char *str1, const char *str2); - boolean takeScreenshot(); - enum graphicsModes setGraphicsMode(enum graphicsModes mode); - boolean controlKeyIsDown(); - boolean shiftKeyIsDown(); - short getHighScoresList(rogueHighScoresEntry returnList[HIGH_SCORES_COUNT]); - boolean saveHighScore(rogueHighScoresEntry theEntry); - fileEntry *listFiles(short *fileCount, char **dynamicMemoryBuffer); - void initializeLaunchArguments(enum NGCommands *command, char *path, uint64_t *seed); - - char nextKeyPress(boolean textInput); - void refreshSideBar(short focusX, short focusY, boolean focusedEntityMustGoFirst); - void printHelpScreen(); - void printDiscoveriesScreen(); - void printHighScores(boolean hiliteMostRecent); - void displayGrid(short **map); - void printSeed(); - void printProgressBar(short x, short y, const char barLabel[COLS], long amtFilled, long amtMax, const color *fillColor, boolean dim); - short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight); - void describeHallucinatedItem(char *buf); - short printItemInfo(item *theItem, short y, boolean dim, boolean highlight); - short printTerrainInfo(short x, short y, short py, const char *description, boolean dim, boolean highlight); - void rectangularShading(short x, short y, short width, short height, - const color *backColor, short opacity, cellDisplayBuffer dbuf[COLS][ROWS]); - short printTextBox(char *textBuf, short x, short y, short width, - const color *foreColor, const color *backColor, - cellDisplayBuffer rbuf[COLS][ROWS], - brogueButton *buttons, short buttonCount); - void printMonsterDetails(creature *monst, cellDisplayBuffer rbuf[COLS][ROWS]); - void printFloorItemDetails(item *theItem, cellDisplayBuffer rbuf[COLS][ROWS]); - unsigned long printCarriedItemDetails(item *theItem, - short x, short y, short width, - boolean includeButtons, - cellDisplayBuffer rbuf[COLS][ROWS]); - void funkyFade(cellDisplayBuffer displayBuf[COLS][ROWS], const color *colorStart, const color *colorEnd, short stepCount, short x, short y, boolean invert); - void displayCenteredAlert(char *message); - void flashMessage(char *message, short x, short y, int time, const color *fColor, const color *bColor); - void flashTemporaryAlert(char *message, int time); - void highlightScreenCell(short x, short y, const color *highlightColor, short strength); - void waitForAcknowledgment(); - void waitForKeystrokeOrMouseClick(); - boolean confirm(char *prompt, boolean alsoDuringPlayback); - void refreshDungeonCell(short x, short y); - void applyColorMultiplier(color *baseColor, const color *multiplierColor); - void applyColorAverage(color *baseColor, const color *newColor, short averageWeight); - void applyColorAugment(color *baseColor, const color *augmentingColor, short augmentWeight); - void applyColorScalar(color *baseColor, short scalar); - void applyColorBounds(color *baseColor, short lowerBound, short upperBound); - void desaturate(color *baseColor, short weight); - void randomizeColor(color *baseColor, short randomizePercent); - void swapColors(color *color1, color *color2); - void irisFadeBetweenBuffers(cellDisplayBuffer fromBuf[COLS][ROWS], - cellDisplayBuffer toBuf[COLS][ROWS], - short x, short y, - short frameCount, - boolean outsideIn); - void colorBlendCell(short x, short y, const color *hiliteColor, short hiliteStrength); - void hiliteCell(short x, short y, const color *hiliteColor, short hiliteStrength, boolean distinctColors); - void colorMultiplierFromDungeonLight(short x, short y, color *editColor); - void plotCharWithColor(enum displayGlyph inputChar, windowpos loc, const color *cellForeColor, const color *cellBackColor); - void plotCharToBuffer(enum displayGlyph inputChar, windowpos loc, const color *foreColor, const color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]); - void plotForegroundChar(enum displayGlyph inputChar, short x, short y, const color *foreColor, boolean affectedByLighting); - void commitDraws(); - void dumpLevelToScreen(); - void hiliteCharGrid(char hiliteCharGrid[DCOLS][DROWS], const color *hiliteColor, short hiliteStrength); - void blackOutScreen(); - void colorOverDungeon(const color *color); - void copyDisplayBuffer(cellDisplayBuffer toBuf[COLS][ROWS], cellDisplayBuffer fromBuf[COLS][ROWS]); - void clearDisplayBuffer(cellDisplayBuffer dbuf[COLS][ROWS]); - color colorFromComponents(char rgb[3]); - void overlayDisplayBuffer(cellDisplayBuffer overBuf[COLS][ROWS], cellDisplayBuffer previousBuf[COLS][ROWS]); - void flashForeground(short *x, short *y, const color **flashColor, short *flashStrength, short count, short frames); - void flashCell(const color *theColor, short frames, short x, short y); - void colorFlash(const color *theColor, unsigned long reqTerrainFlags, unsigned long reqTileFlags, short frames, short maxRadius, short x, short y); - void printString(const char *theString, short x, short y, const color *foreColor, const color* backColor, cellDisplayBuffer dbuf[COLS][ROWS]); - short wrapText(char *to, const char *sourceText, short width); - short printStringWithWrapping(const char *theString, short x, short y, short width, const color *foreColor, - const color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]); - boolean getInputTextString(char *inputText, - const char *prompt, - short maxLength, - const char *defaultEntry, - const char *promptSuffix, - short textEntryType, - boolean useDialogBox); - void displayChokeMap(); - void displayLoops(); - boolean pauseBrogue(short milliseconds); - boolean pauseAnimation(short milliseconds); - void nextBrogueEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance, boolean realInputEvenInPlayback); - void executeMouseClick(rogueEvent *theEvent); - void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKey); - void initializeLevel(); - void startLevel (short oldLevelNumber, short stairDirection); - void updateMinersLightRadius(); - void freeCreature(creature *monst); - void freeCreatureList(creatureList *list); - void removeDeadMonsters(); - void freeEverything(); - boolean randomMatchingLocation(short *x, short *y, short dungeonType, short liquidType, short terrainType); - enum dungeonLayers highestPriorityLayer(short x, short y, boolean skipGas); - enum dungeonLayers layerWithTMFlag(short x, short y, unsigned long flag); - enum dungeonLayers layerWithFlag(short x, short y, unsigned long flag); - const char *tileFlavor(short x, short y); - const char *tileText(short x, short y); - void describedItemBasedOnParameters(short theCategory, short theKind, short theQuantity, short theItemOriginDepth, char *buf); - void describeLocation(char buf[DCOLS], short x, short y); - void printLocationDescription(short x, short y); - void useKeyAt(item *theItem, short x, short y); - void playerRuns(short direction); - void exposeCreatureToFire(creature *monst); - void updateFlavorText(); - void updatePlayerUnderwaterness(); - boolean monsterShouldFall(creature *monst); - void applyInstantTileEffectsToCreature(creature *monst); - void vomit(creature *monst); - void becomeAllyWith(creature *monst); - void freeCaptive(creature *monst); - boolean freeCaptivesEmbeddedAt(short x, short y); - boolean handleWhipAttacks(creature *attacker, enum directions dir, boolean *aborted); - boolean handleSpearAttacks(creature *attacker, enum directions dir, boolean *aborted); - boolean diagonalBlocked(const short x1, const short y1, const short x2, const short y2, const boolean limitToPlayerKnowledge); - boolean playerMoves(short direction); - void calculateDistances(short **distanceMap, - short destinationX, short destinationY, - unsigned long blockingTerrainFlags, - creature *traveler, - boolean canUseSecretDoors, - boolean eightWays); - short pathingDistance(short x1, short y1, short x2, short y2, unsigned long blockingTerrainFlags); - short nextStep(short **distanceMap, short x, short y, creature *monst, boolean reverseDirections); - void travelRoute(pos path[1000], short steps); - void travel(short x, short y, boolean autoConfirm); - void populateGenericCostMap(short **costMap); - void getLocationFlags(const short x, const short y, - unsigned long *tFlags, unsigned long *TMFlags, unsigned long *cellFlags, - const boolean limitToPlayerKnowledge); - void populateCreatureCostMap(short **costMap, creature *monst); - enum directions adjacentFightingDir(); - void getExploreMap(short **map, boolean headingToStairs); - boolean explore(short frameDelay); - short getPlayerPathOnMap(pos path[1000], short **map, pos origin); - void reversePath(pos path[1000], short steps); - void hilitePath(pos path[1000], short steps, boolean unhilite); - void clearCursorPath(); - void hideCursor(); - void showCursor(); - void mainInputLoop(); - boolean isDisturbed(short x, short y); - void discover(short x, short y); - short randValidDirectionFrom(creature *monst, short x, short y, boolean respectAvoidancePreferences); - boolean exposeTileToElectricity(short x, short y); - boolean exposeTileToFire(short x, short y, boolean alwaysIgnite); - boolean cellCanHoldGas(short x, short y); - void monstersFall(); - void updateEnvironment(); - void updateAllySafetyMap(); - void updateSafetyMap(); - void updateSafeTerrainMap(); - short staffChargeDuration(const item *theItem); - void rechargeItemsIncrementally(short multiplier); - void extinguishFireOnCreature(creature *monst); - void autoRest(); - void manualSearch(); - boolean startFighting(enum directions dir, boolean tillDeath); - void autoFight(boolean tillDeath); - void synchronizePlayerTimeState(); - void playerRecoversFromAttacking(boolean anAttackHit); - void playerTurnEnded(); - void resetScentTurnNumber(); - void displayMonsterFlashes(boolean flashingEnabled); - void clearMessageArchive(); - void formatRecentMessages(char buf[][COLS*2], size_t height, short *linesFormatted, short *latestMessageLines); - void displayRecentMessages(); - void displayMessageArchive(); - void temporaryMessage(const char *msg1, unsigned long flags); - void messageWithColor(const char *msg, const color *theColor, unsigned long flags); - void flavorMessage(const char *msg); - void message(const char *msg, unsigned long flags); - void displayMoreSignWithoutWaitingForAcknowledgment(); - void displayMoreSign(); - short encodeMessageColor(char *msg, short i, const color *theColor); - short decodeMessageColor(const char *msg, short i, color *returnColor); - const color *messageColorFromVictim(creature *monst); - void upperCase(char *theChar); - void updateMessageDisplay(); - void deleteMessages(); - void confirmMessages(); - void stripShiftFromMovementKeystroke(signed long *keystroke); - - void storeMemories(const short x, const short y); - void updateFieldOfViewDisplay(boolean updateDancingTerrain, boolean refreshDisplay); - void updateFieldOfView(short xLoc, short yLoc, short radius, boolean paintScent, - boolean passThroughCreatures, boolean setFieldOfView, short theColor[3], short fadeToPercent); - void betweenOctant1andN(short *x, short *y, short x0, short y0, short n); - - void getFOVMask(char grid[DCOLS][DROWS], short xLoc, short yLoc, fixpt maxRadius, - unsigned long forbiddenTerrain, unsigned long forbiddenFlags, boolean cautiousOnWalls); - void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant, fixpt maxRadius, - short columnsRightFromOrigin, long startSlope, long endSlope, unsigned long forbiddenTerrain, - unsigned long forbiddenFlags, boolean cautiousOnWalls); - - creature *generateMonster(short monsterID, boolean itemPossible, boolean mutationPossible); - void mutateMonster(creature *monst, short mutationIndex); - short chooseMonster(short forLevel); - creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFlags, unsigned long requiredFlags); - void fadeInMonster(creature *monst); - - creatureList createCreatureList(); - creatureIterator iterateCreatures(creatureList *list); - boolean hasNextCreature(creatureIterator iter); - creature *nextCreature(creatureIterator *iter); - void prependCreature(creatureList *list, creature *add); - boolean removeCreature(creatureList *list, creature *remove); - creature *firstCreature(creatureList *list); - - boolean monsterWillAttackTarget(const creature *attacker, const creature *defender); - boolean monstersAreTeammates(const creature *monst1, const creature *monst2); - boolean monstersAreEnemies(const creature *monst1, const creature *monst2); - void initializeGender(creature *monst); - boolean stringsMatch(const char *str1, const char *str2); - void resolvePronounEscapes(char *text, creature *monst); - short pickHordeType(short depth, enum monsterTypes summonerType, unsigned long forbiddenFlags, unsigned long requiredFlags); - creature *cloneMonster(creature *monst, boolean announce, boolean placeClone); - void empowerMonster(creature *monst); - unsigned long forbiddenFlagsForMonster(creatureType *monsterType); - unsigned long avoidedFlagsForMonster(creatureType *monsterType); - boolean monsterCanSubmergeNow(creature *monst); - void populateMonsters(); - void updateMonsterState(creature *monst); - void decrementMonsterStatus(creature *monst); - boolean specifiedPathBetween(short x1, short y1, short x2, short y2, - unsigned long blockingTerrain, unsigned long blockingFlags); - boolean traversiblePathBetween(creature *monst, short x2, short y2); - boolean openPathBetween(short x1, short y1, short x2, short y2); - creature *monsterAtLoc(pos p); - creature *dormantMonsterAtLoc(pos p); - pos perimeterCoords(short n); - boolean monsterBlinkToPreferenceMap(creature *monst, short **preferenceMap, boolean blinkUphill); - boolean monsterSummons(creature *monst, boolean alwaysUse); - boolean resurrectAlly(const short x, const short y); - void unAlly(creature *monst); - boolean monsterFleesFrom(creature *monst, creature *defender); - void monstersTurn(creature *monst); - boolean getRandomMonsterSpawnLocation(short *x, short *y); - void spawnPeriodicHorde(); - void clearStatus(creature *monst); - void moralAttack(creature *attacker, creature *defender); - short runicWeaponChance(item *theItem, boolean customEnchantLevel, fixpt enchantLevel); - void magicWeaponHit(creature *defender, item *theItem, boolean backstabbed); - void disentangle(creature *monst); - void teleport(creature *monst, short x, short y, boolean respectTerrainAvoidancePreferences); - void chooseNewWanderDestination(creature *monst); - boolean canPass(creature *mover, creature *blocker); - boolean isPassableOrSecretDoor(short x, short y); - boolean knownToPlayerAsPassableOrSecretDoor(short x, short y); - void setMonsterLocation(creature *monst, short newX, short newY); - boolean moveMonster(creature *monst, short dx, short dy); - unsigned long burnedTerrainFlagsAtLoc(short x, short y); - unsigned long discoveredTerrainFlagsAtLoc(short x, short y); - boolean monsterAvoids(creature *monst, pos p); - short distanceBetween(pos loc1, pos loc2); - void alertMonster(creature *monst); - void wakeUp(creature *monst); - boolean monsterRevealed(creature *monst); - boolean monsterHiddenBySubmersion(const creature *monst, const creature *observer); - boolean monsterIsHidden(const creature *monst, const creature *observer); - boolean canSeeMonster(creature *monst); - boolean canDirectlySeeMonster(creature *monst); - void monsterName(char *buf, creature *monst, boolean includeArticle); - boolean monsterIsInClass(const creature *monst, const short monsterClass); - boolean chooseTarget(pos *returnLoc, short maxDistance, boolean stopAtTarget, boolean autoTarget, - boolean targetAllies, const bolt *theBolt, const color *trajectoryColor); - fixpt strengthModifier(item *theItem); - fixpt netEnchant(item *theItem); - short hitProbability(creature *attacker, creature *defender); - boolean attackHit(creature *attacker, creature *defender); - void applyArmorRunicEffect(char returnString[DCOLS], creature *attacker, short *damage, boolean melee); - void processStaggerHit(creature *attacker, creature *defender); - boolean attack(creature *attacker, creature *defender, boolean lungeAttack); - void inflictLethalDamage(creature *attacker, creature *defender); - boolean inflictDamage(creature *attacker, creature *defender, - short damage, const color *flashColor, boolean ignoresProtectionShield); - void addPoison(creature *monst, short totalDamage, short concentrationIncrement); - void killCreature(creature *decedent, boolean administrativeDeath); - void buildHitList(creature **hitList, const creature *attacker, creature *defender, const boolean sweep); - void addScentToCell(short x, short y, short distance); - void populateItems(short upstairsX, short upstairsY); - item *placeItem(item *theItem, short x, short y); - void removeItemFrom(short x, short y); - void pickUpItemAt(short x, short y); - item *addItemToPack(item *theItem); - void aggravateMonsters(short distance, short x, short y, const color *flashColor); - short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos targetLoc, const bolt *theBolt); - void getImpactLoc(pos *returnLoc, const pos originLoc, const pos targetLoc, - const short maxDistance, const boolean returnLastEmptySpace, const bolt *theBolt); - boolean negate(creature *monst); - short monsterAccuracyAdjusted(const creature *monst); - fixpt monsterDamageAdjustmentAmount(const creature *monst); - short monsterDefenseAdjusted(const creature *monst); - void weaken(creature *monst, short maxDuration); - void slow(creature *monst, short turns); - void haste(creature *monst, short turns); - void heal(creature *monst, short percent, boolean panacea); - boolean projectileReflects(creature *attacker, creature *defender); - short reflectBolt(short targetX, short targetY, pos listOfCoordinates[], short kinkCell, boolean retracePath); - void checkForMissingKeys(short x, short y); - enum boltEffects boltEffectForItem(item *theItem); - enum boltType boltForItem(item *theItem); - boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, boolean reverseBoltDir); - boolean nextTargetAfter(short *returnX, - short *returnY, - short targetX, - short targetY, - boolean targetEnemies, - boolean targetAllies, - boolean targetItems, - boolean targetTerrain, - boolean requireOpenPath, - boolean reverseDirection); - boolean moveCursor(boolean *targetConfirmed, - boolean *canceled, - boolean *tabKey, - pos *targetLoc, - rogueEvent *event, - buttonState *state, - boolean colorsDance, - boolean keysMoveCursor, - boolean targetCanLeaveMap); - void identifyItemKind(item *theItem); - void autoIdentify(item *theItem); - short numberOfItemsInPack(); - char nextAvailableInventoryCharacter(); - void checkForDisenchantment(item *theItem); - void updateFloorItems(); - void itemKindName(item *theItem, char *kindName); - void itemRunicName(item *theItem, char *runicName); - void itemName(item *theItem, char *root, boolean includeDetails, boolean includeArticle, const color *baseColor); - int itemKindCount(enum itemCategory category, int magicPolarity); - char displayInventory(unsigned short categoryMask, - unsigned long requiredFlags, - unsigned long forbiddenFlags, - boolean waitForAcknowledge, - boolean includeButtons); - short numberOfMatchingPackItems(unsigned short categoryMask, - unsigned long requiredFlags, unsigned long forbiddenFlags, - boolean displayErrors); - void clearInventory(char keystroke); - item *initializeItem(); - item *generateItem(unsigned short theCategory, short theKind); - short chooseKind(const itemTable *theTable, short numKinds); - item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind); - void updateEncumbrance(); - short displayedArmorValue(); - short armorValueIfUnenchanted(item *theItem); - void strengthCheck(item *theItem, boolean noisy); - void recalculateEquipmentBonuses(); - boolean equipItem(item *theItem, boolean force, item *unequipHint); - void equip(item *theItem); - item *keyInPackFor(short x, short y); - item *keyOnTileAt(short x, short y); - void unequip(item *theItem); - void drop(item *theItem); - void findAlternativeHomeFor(creature *monst, short *x, short *y, boolean chooseRandomly); - boolean getQualifyingLocNear(pos *loc, - short x, short y, - boolean hallwaysAllowed, - char blockingMap[DCOLS][DROWS], - unsigned long forbiddenTerrainFlags, - unsigned long forbiddenMapFlags, - boolean forbidLiquid, - boolean deterministic); - boolean getQualifyingGridLocNear(pos *loc, - short x, short y, - boolean grid[DCOLS][DROWS], - boolean deterministic); - - // Grid operations - short **allocGrid(); - void freeGrid(short **array); - void copyGrid(short **to, short **from); - void fillGrid(short **grid, short fillValue); - void hiliteGrid(short **grid, const color *hiliteColor, short hiliteStrength); - void findReplaceGrid(short **grid, short findValueMin, short findValueMax, short fillValue); - short floodFillGrid(short **grid, short x, short y, short eligibleValueMin, short eligibleValueMax, short fillValue); - void drawRectangleOnGrid(short **grid, short x, short y, short width, short height, short value); - void drawCircleOnGrid(short **grid, short x, short y, short radius, short value); - void getTerrainGrid(short **grid, short value, unsigned long terrainFlags, unsigned long mapFlags); - void getTMGrid(short **grid, short value, unsigned long TMflags); - short validLocationCount(short **grid, short validValue); - void randomLocationInGrid(short **grid, short *x, short *y, short validValue); - boolean getQualifyingPathLocNear(short *retValX, short *retValY, - short x, short y, - boolean hallwaysAllowed, - unsigned long blockingTerrainFlags, - unsigned long blockingMapFlags, - unsigned long forbiddenTerrainFlags, - unsigned long forbiddenMapFlags, - boolean deterministic); - void createBlobOnGrid(short **grid, - short *retMinX, short *retMinY, short *retWidth, short *retHeight, - short roundCount, - short minBlobWidth, short minBlobHeight, - short maxBlobWidth, short maxBlobHeight, short percentSeeded, - char birthParameters[9], char survivalParameters[9]); - - void checkForContinuedLeadership(creature *monst); - void demoteMonsterFromLeadership(creature *monst); - void toggleMonsterDormancy(creature *monst); - void monsterDetails(char buf[], creature *monst); - void makeMonsterDropItem(creature *monst); - void throwCommand(item *theItem, boolean autoThrow); - void relabel(item *theItem); - void swapLastEquipment(); - void apply(item *theItem, boolean recordCommands); - boolean itemCanBeCalled(item *theItem); - void call(item *theItem); - short chooseVorpalEnemy(); - void describeMonsterClass(char *buf, const short classID, boolean conjunctionAnd); - void identify(item *theItem); - void updateIdentifiableItem(item *theItem); - void updateIdentifiableItems(); - void readScroll(item *theItem); - void updateRingBonuses(); - void updatePlayerRegenerationDelay(); - boolean removeItemFromChain(item *theItem, item *theChain); - void addItemToChain(item *theItem, item *theChain); - void drinkPotion(item *theItem); - item *promptForItemOfType(unsigned short category, - unsigned long requiredFlags, - unsigned long forbiddenFlags, - char *prompt, - boolean allowInventoryActions); - item *itemOfPackLetter(char letter); - boolean unequipItem(item *theItem, boolean force); - short magicCharDiscoverySuffix(short category, short kind); - int itemMagicPolarity(item *theItem); - item *itemAtLoc(short x, short y); - item *dropItem(item *theItem); - itemTable *tableForItemCategory(enum itemCategory theCat); - boolean isVowelish(char *theChar); - short charmEffectDuration(short charmKind, short enchant); - short charmRechargeDelay(short charmKind, short enchant); - boolean itemIsCarried(item *theItem); - void itemDetails(char *buf, item *theItem); - void deleteItem(item *theItem); - void shuffleFlavors(); - unsigned long itemValue(item *theItem); - short strLenWithoutEscapes(const char *str); - void combatMessage(char *theMsg, const color *theColor); - void displayCombatText(); - void flashMonster(creature *monst, const color *theColor, short strength); - - boolean paintLight(const lightSource *theLight, short x, short y, boolean isMinersLight, boolean maintainShadows); - void backUpLighting(short lights[DCOLS][DROWS][3]); - void restoreLighting(short lights[DCOLS][DROWS][3]); - void updateLighting(); - boolean playerInDarkness(); - flare *newFlare(const lightSource *light, short x, short y, short changePerFrame, short limit); - void createFlare(short x, short y, enum lightType lightIndex); - void animateFlares(flare **flares, short count); - void deleteAllFlares(); - void demoteVisibility(); - void discoverCell(const short x, const short y); - void updateVision(boolean refreshDisplay); - void burnItem(item *theItem); - void activateMachine(short machineNumber); - boolean circuitBreakersPreventActivation(short machineNumber); - void promoteTile(short x, short y, enum dungeonLayers layer, boolean useFireDF); - void autoPlayLevel(boolean fastForward); - void updateClairvoyance(); - short scentDistance(short x1, short y1, short x2, short y2); - short armorStealthAdjustment(item *theArmor); - short currentStealthRange(); - - void initRecording(); - void flushBufferToFile(); - void fillBufferFromFile(); - void recordEvent(rogueEvent *event); - void recallEvent(rogueEvent *event); - void pausePlayback(); - void displayAnnotation(); - boolean loadSavedGame(); - void switchToPlaying(); - void recordKeystroke(int keystroke, boolean controlKey, boolean shiftKey); - void cancelKeystroke(); - void recordKeystrokeSequence(unsigned char *commandSequence); - void recordMouseClick(short x, short y, boolean controlKey, boolean shiftKey); - void OOSCheck(unsigned long x, short numberOfBytes); - void RNGCheck(); - boolean executePlaybackInput(rogueEvent *recordingInput); - void getAvailableFilePath(char *filePath, const char *defaultPath, const char *suffix); - boolean characterForbiddenInFilename(const char theChar); - void saveGame(); - void saveGameNoPrompt(); - void saveRecording(char *filePath); - void saveRecordingNoPrompt(char *filePath); - void parseFile(); - void RNGLog(char *message); - - short wandDominate(creature *monst); - short staffDamageLow(fixpt enchant); - short staffDamageHigh(fixpt enchant); - short staffDamage(fixpt enchant); - int staffPoison(fixpt enchant); - short staffBlinkDistance(fixpt enchant); - short staffHasteDuration(fixpt enchant); - short staffBladeCount(fixpt enchant); - short staffDiscordDuration(fixpt enchant); - int staffProtection(fixpt enchant); - short staffEntrancementDuration(fixpt enchant); - fixpt ringWisdomMultiplier(fixpt enchant); - short charmHealing(fixpt enchant); - int charmProtection(fixpt enchant); - short charmShattering(fixpt enchant); - short charmGuardianLifespan(fixpt enchant); - short charmNegationRadius(fixpt enchant); - short weaponParalysisDuration(fixpt enchant); - short weaponConfusionDuration(fixpt enchant); - short weaponForceDistance(fixpt enchant); - short weaponSlowDuration(fixpt enchant); - short weaponImageCount(fixpt enchant); - short weaponImageDuration(fixpt enchant); - short armorReprisalPercent(fixpt enchant); - short armorAbsorptionMax(fixpt enchant); - short armorImageCount(fixpt enchant); - short reflectionChance(fixpt enchant); - long turnsForFullRegenInThousandths(fixpt bonus); - fixpt damageFraction(fixpt netEnchant); - fixpt accuracyFraction(fixpt netEnchant); - fixpt defenseFraction(fixpt netDefense); - - void checkForDungeonErrors(); - - boolean dialogChooseFile(char *path, const char *suffix, const char *prompt); - void dialogCreateItemOrMonster(); - int quitImmediately(); - void dialogAlert(char *message); - void mainBrogueJunction(); - void printSeedCatalog(uint64_t startingSeed, uint64_t numberOfSeedsToScan, unsigned int scanThroughDepth, boolean isCsvFormat); - - void initializeButton(brogueButton *button); - void drawButtonsInState(buttonState *state); - void initializeButtonState(buttonState *state, - brogueButton *buttons, - short buttonCount, - short winX, - short winY, - short winWidth, - short winHeight); - short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *event); - short smoothHiliteGradient(const short currentXValue, const short maxXValue); - void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDisplayBuffer dbuf[COLS][ROWS]); - short buttonInputLoop(brogueButton *buttons, - short buttonCount, - short winX, - short winY, - short winWidth, - short winHeight, - rogueEvent *returnEvent); - - void dijkstraScan(short **distanceMap, short **costMap, boolean useDiagonals); +// Utilities.c - String functions +boolean endswith(const char *str, const char *ending); +void append(char *str, char *ending, int bufsize); + +int rogueMain(); +void printBrogueVersion(); +void executeEvent(rogueEvent *theEvent); +boolean fileExists(const char *pathname); +boolean chooseFile(char *path, char *prompt, char *defaultName, char *suffix); +boolean openFile(const char *path); +void initializeGameVariant(); +void initializeRogue(uint64_t seed); +void gameOver(char *killedBy, boolean useCustomPhrasing); +void victory(boolean superVictory); +void initializeDynamicColors(); +void enableEasyMode(); +boolean tryParseUint64(char *str, uint64_t *num); +uint64_t rand_64bits(); +long rand_range(long lowerBound, long upperBound); +uint64_t seedRandomGenerator(uint64_t seed); +short randClumpedRange(short lowerBound, short upperBound, short clumpFactor); +short randClump(randomRange theRange); +boolean rand_percent(short percent); +void shuffleList(short *list, short listLength); +void fillSequentialList(short *list, short listLength); +fixpt fp_round(fixpt x); +fixpt fp_pow(fixpt base, int expn); +fixpt fp_sqrt(fixpt val); +short unflag(unsigned long flag); +void considerCautiousMode(); +void refreshScreen(); +void displayLevel(); +void storeColorComponents(char components[3], const color *theColor); +boolean separateColors(color *fore, const color *back); +void bakeColor(color *theColor); +void shuffleTerrainColors(short percentOfCells, boolean refreshCells); +void normColor(color *baseColor, const short aggregateMultiplier, const short colorTranslation); +void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *returnForeColor, color *returnBackColor); +void logBuffer(char array[DCOLS][DROWS]); +// void logBuffer(short **array); +boolean search(short searchStrength); +boolean proposeOrConfirmLocation(short x, short y, char *failureMessage); +boolean useStairs(short stairDirection); +short passableArcCount(short x, short y); +void analyzeMap(boolean calculateChokeMap); +boolean buildAMachine(enum machineTypes bp, short originX, short originY, unsigned long requiredMachineFlags, item *adoptiveItem, item *parentSpawnedItems[50], creature *parentSpawnedMonsters[50]); +void attachRooms(short **grid, const dungeonProfile *theDP, short attempts, short maxRoomCount); +void digDungeon(); +void updateMapToShore(); +short levelIsDisconnectedWithBlockingMap(char blockingMap[DCOLS][DROWS], boolean countRegionSize); +void resetDFMessageEligibility(); +boolean fillSpawnMap(enum dungeonLayers layer, enum tileType surfaceTileType, char spawnMap[DCOLS][DROWS], boolean blockedByOtherLayers, boolean refresh, boolean superpriority); +boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refreshCell, boolean abortIfBlocking); +void restoreMonster(creature *monst, short **mapToStairs, short **mapToPit); +void restoreItem(item *theItem); +void refreshWaypoint(short wpIndex); +void setUpWaypoints(); +void zeroOutGrid(char grid[DCOLS][DROWS]); +short oppositeDirection(short theDir); + +void plotChar(enum displayGlyph inputChar, short xLoc, short yLoc, short backRed, short backGreen, short backBlue, short foreRed, short foreGreen, short foreBlue); +boolean pauseForMilliseconds(short milliseconds); +boolean isApplicationActive(); +void nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance); +void notifyEvent(short eventId, int data1, int data2, const char *str1, const char *str2); +boolean takeScreenshot(); +enum graphicsModes setGraphicsMode(enum graphicsModes mode); +boolean controlKeyIsDown(); +boolean shiftKeyIsDown(); +short getHighScoresList(rogueHighScoresEntry returnList[HIGH_SCORES_COUNT]); +boolean saveHighScore(rogueHighScoresEntry theEntry); +fileEntry *listFiles(short *fileCount, char **dynamicMemoryBuffer); +void initializeLaunchArguments(enum NGCommands *command, char *path, uint64_t *seed); + +char nextKeyPress(boolean textInput); +void refreshSideBar(short focusX, short focusY, boolean focusedEntityMustGoFirst); +void printHelpScreen(); +void printDiscoveriesScreen(); +void printHighScores(boolean hiliteMostRecent); +void displayGrid(short **map); +void printSeed(); +void printProgressBar(short x, short y, const char barLabel[COLS], long amtFilled, long amtMax, const color *fillColor, boolean dim); +short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight); +void describeHallucinatedItem(char *buf); +short printItemInfo(item *theItem, short y, boolean dim, boolean highlight); +short printTerrainInfo(short x, short y, short py, const char *description, boolean dim, boolean highlight); +void rectangularShading(short x, short y, short width, short height, const color *backColor, short opacity, cellDisplayBuffer dbuf[COLS][ROWS]); +short printTextBox(char *textBuf, short x, short y, short width, const color *foreColor, const color *backColor, cellDisplayBuffer rbuf[COLS][ROWS], brogueButton *buttons, short buttonCount); +void printMonsterDetails(creature *monst, cellDisplayBuffer rbuf[COLS][ROWS]); +void printFloorItemDetails(item *theItem, cellDisplayBuffer rbuf[COLS][ROWS]); +unsigned long printCarriedItemDetails(item *theItem, short x, short y, short width, boolean includeButtons, cellDisplayBuffer rbuf[COLS][ROWS]); +void funkyFade(cellDisplayBuffer displayBuf[COLS][ROWS], const color *colorStart, const color *colorEnd, short stepCount, short x, short y, boolean invert); +void displayCenteredAlert(char *message); +void flashMessage(char *message, short x, short y, int time, const color *fColor, const color *bColor); +void flashTemporaryAlert(char *message, int time); +void highlightScreenCell(short x, short y, const color *highlightColor, short strength); +void waitForAcknowledgment(); +void waitForKeystrokeOrMouseClick(); +boolean confirm(char *prompt, boolean alsoDuringPlayback); +void refreshDungeonCell(short x, short y); +void applyColorMultiplier(color *baseColor, const color *multiplierColor); +void applyColorAverage(color *baseColor, const color *newColor, short averageWeight); +void applyColorAugment(color *baseColor, const color *augmentingColor, short augmentWeight); +void applyColorScalar(color *baseColor, short scalar); +void applyColorBounds(color *baseColor, short lowerBound, short upperBound); +void desaturate(color *baseColor, short weight); +void randomizeColor(color *baseColor, short randomizePercent); +void swapColors(color *color1, color *color2); +void irisFadeBetweenBuffers(cellDisplayBuffer fromBuf[COLS][ROWS], cellDisplayBuffer toBuf[COLS][ROWS], short x, short y, short frameCount, boolean outsideIn); +void colorBlendCell(short x, short y, const color *hiliteColor, short hiliteStrength); +void hiliteCell(short x, short y, const color *hiliteColor, short hiliteStrength, boolean distinctColors); +void colorMultiplierFromDungeonLight(short x, short y, color *editColor); +void plotCharWithColor(enum displayGlyph inputChar, windowpos loc, const color *cellForeColor, const color *cellBackColor); +void plotCharToBuffer(enum displayGlyph inputChar, windowpos loc, const color *foreColor, const color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]); +void plotForegroundChar(enum displayGlyph inputChar, short x, short y, const color *foreColor, boolean affectedByLighting); +void commitDraws(); +void dumpLevelToScreen(); +void hiliteCharGrid(char hiliteCharGrid[DCOLS][DROWS], const color *hiliteColor, short hiliteStrength); +void blackOutScreen(); +void colorOverDungeon(const color *color); +void copyDisplayBuffer(cellDisplayBuffer toBuf[COLS][ROWS], cellDisplayBuffer fromBuf[COLS][ROWS]); +void clearDisplayBuffer(cellDisplayBuffer dbuf[COLS][ROWS]); +color colorFromComponents(char rgb[3]); +void overlayDisplayBuffer(cellDisplayBuffer overBuf[COLS][ROWS], cellDisplayBuffer previousBuf[COLS][ROWS]); +void flashForeground(short *x, short *y, const color **flashColor, short *flashStrength, short count, short frames); +void flashCell(const color *theColor, short frames, short x, short y); +void colorFlash(const color *theColor, unsigned long reqTerrainFlags, unsigned long reqTileFlags, short frames, short maxRadius, short x, short y); +void printString(const char *theString, short x, short y, const color *foreColor, const color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]); +short wrapText(char *to, const char *sourceText, short width); +short printStringWithWrapping(const char *theString, short x, short y, short width, const color *foreColor, const color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]); +boolean getInputTextString(char *inputText, const char *prompt, short maxLength, const char *defaultEntry, const char *promptSuffix, short textEntryType, boolean useDialogBox); +void displayChokeMap(); +void displayLoops(); +boolean pauseBrogue(short milliseconds); +boolean pauseAnimation(short milliseconds); +void nextBrogueEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance, boolean realInputEvenInPlayback); +void executeMouseClick(rogueEvent *theEvent); +void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKey); +void initializeLevel(); +void startLevel(short oldLevelNumber, short stairDirection); +void updateMinersLightRadius(); +void freeCreature(creature *monst); +void freeCreatureList(creatureList *list); +void removeDeadMonsters(); +void freeEverything(); +boolean randomMatchingLocation(short *x, short *y, short dungeonType, short liquidType, short terrainType); +enum dungeonLayers highestPriorityLayer(short x, short y, boolean skipGas); +enum dungeonLayers layerWithTMFlag(short x, short y, unsigned long flag); +enum dungeonLayers layerWithFlag(short x, short y, unsigned long flag); +const char *tileFlavor(short x, short y); +const char *tileText(short x, short y); +void describedItemBasedOnParameters(short theCategory, short theKind, short theQuantity, short theItemOriginDepth, char *buf); +void describeLocation(char buf[DCOLS], short x, short y); +void printLocationDescription(short x, short y); +void useKeyAt(item *theItem, short x, short y); +void playerRuns(short direction); +void exposeCreatureToFire(creature *monst); +void updateFlavorText(); +void updatePlayerUnderwaterness(); +boolean monsterShouldFall(creature *monst); +void applyInstantTileEffectsToCreature(creature *monst); +void vomit(creature *monst); +void becomeAllyWith(creature *monst); +void freeCaptive(creature *monst); +boolean freeCaptivesEmbeddedAt(short x, short y); +boolean handleWhipAttacks(creature *attacker, enum directions dir, boolean *aborted); +boolean handleSpearAttacks(creature *attacker, enum directions dir, boolean *aborted); +boolean diagonalBlocked(const short x1, const short y1, const short x2, const short y2, const boolean limitToPlayerKnowledge); +boolean playerMoves(short direction); +void calculateDistances(short **distanceMap, short destinationX, short destinationY, unsigned long blockingTerrainFlags, creature *traveler, boolean canUseSecretDoors, boolean eightWays); +short pathingDistance(short x1, short y1, short x2, short y2, unsigned long blockingTerrainFlags); +short nextStep(short **distanceMap, short x, short y, creature *monst, boolean reverseDirections); +void travelRoute(pos path[1000], short steps); +void travel(short x, short y, boolean autoConfirm); +void populateGenericCostMap(short **costMap); +void getLocationFlags(const short x, const short y, unsigned long *tFlags, unsigned long *TMFlags, unsigned long *cellFlags, const boolean limitToPlayerKnowledge); +void populateCreatureCostMap(short **costMap, creature *monst); +enum directions adjacentFightingDir(); +void getExploreMap(short **map, boolean headingToStairs); +boolean explore(short frameDelay); +short getPlayerPathOnMap(pos path[1000], short **map, pos origin); +void reversePath(pos path[1000], short steps); +void hilitePath(pos path[1000], short steps, boolean unhilite); +void clearCursorPath(); +void hideCursor(); +void showCursor(); +void mainInputLoop(); +boolean isDisturbed(short x, short y); +void discover(short x, short y); +short randValidDirectionFrom(creature *monst, short x, short y, boolean respectAvoidancePreferences); +boolean exposeTileToElectricity(short x, short y); +boolean exposeTileToFire(short x, short y, boolean alwaysIgnite); +boolean cellCanHoldGas(short x, short y); +void monstersFall(); +void updateEnvironment(); +void updateAllySafetyMap(); +void updateSafetyMap(); +void updateSafeTerrainMap(); +short staffChargeDuration(const item *theItem); +void rechargeItemsIncrementally(short multiplier); +void extinguishFireOnCreature(creature *monst); +void autoRest(); +void manualSearch(); +boolean startFighting(enum directions dir, boolean tillDeath); +void autoFight(boolean tillDeath); +void synchronizePlayerTimeState(); +void playerRecoversFromAttacking(boolean anAttackHit); +void playerTurnEnded(); +void resetScentTurnNumber(); +void displayMonsterFlashes(boolean flashingEnabled); +void clearMessageArchive(); +void formatRecentMessages(char buf[][COLS * 2], size_t height, short *linesFormatted, short *latestMessageLines); +void displayRecentMessages(); +void displayMessageArchive(); +void temporaryMessage(const char *msg1, unsigned long flags); +void messageWithColor(const char *msg, const color *theColor, unsigned long flags); +void flavorMessage(const char *msg); +void message(const char *msg, unsigned long flags); +void displayMoreSignWithoutWaitingForAcknowledgment(); +void displayMoreSign(); +short encodeMessageColor(char *msg, short i, const color *theColor); +short decodeMessageColor(const char *msg, short i, color *returnColor); +const color *messageColorFromVictim(creature *monst); +void upperCase(char *theChar); +void updateMessageDisplay(); +void deleteMessages(); +void confirmMessages(); +void stripShiftFromMovementKeystroke(signed long *keystroke); + +void storeMemories(const short x, const short y); +void updateFieldOfViewDisplay(boolean updateDancingTerrain, boolean refreshDisplay); +void updateFieldOfView(short xLoc, short yLoc, short radius, boolean paintScent, boolean passThroughCreatures, boolean setFieldOfView, short theColor[3], short fadeToPercent); +void betweenOctant1andN(short *x, short *y, short x0, short y0, short n); + +void getFOVMask(char grid[DCOLS][DROWS], short xLoc, short yLoc, fixpt maxRadius, unsigned long forbiddenTerrain, unsigned long forbiddenFlags, boolean cautiousOnWalls); +void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant, fixpt maxRadius, short columnsRightFromOrigin, long startSlope, long endSlope, unsigned long forbiddenTerrain, unsigned long forbiddenFlags, + boolean cautiousOnWalls); + +creature *generateMonster(short monsterID, boolean itemPossible, boolean mutationPossible); +void mutateMonster(creature *monst, short mutationIndex); +short chooseMonster(short forLevel); +creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFlags, unsigned long requiredFlags); +void fadeInMonster(creature *monst); + +creatureList createCreatureList(); +creatureIterator iterateCreatures(creatureList *list); +boolean hasNextCreature(creatureIterator iter); +creature *nextCreature(creatureIterator *iter); +void prependCreature(creatureList *list, creature *add); +boolean removeCreature(creatureList *list, creature *remove); +creature *firstCreature(creatureList *list); + +boolean monsterWillAttackTarget(const creature *attacker, const creature *defender); +boolean monstersAreTeammates(const creature *monst1, const creature *monst2); +boolean monstersAreEnemies(const creature *monst1, const creature *monst2); +void initializeGender(creature *monst); +boolean stringsMatch(const char *str1, const char *str2); +void resolvePronounEscapes(char *text, creature *monst); +short pickHordeType(short depth, enum monsterTypes summonerType, unsigned long forbiddenFlags, unsigned long requiredFlags); +creature *cloneMonster(creature *monst, boolean announce, boolean placeClone); +void empowerMonster(creature *monst); +unsigned long forbiddenFlagsForMonster(creatureType *monsterType); +unsigned long avoidedFlagsForMonster(creatureType *monsterType); +boolean monsterCanSubmergeNow(creature *monst); +void populateMonsters(); +void updateMonsterState(creature *monst); +void decrementMonsterStatus(creature *monst); +boolean specifiedPathBetween(short x1, short y1, short x2, short y2, unsigned long blockingTerrain, unsigned long blockingFlags); +boolean traversiblePathBetween(creature *monst, short x2, short y2); +boolean openPathBetween(short x1, short y1, short x2, short y2); +creature *monsterAtLoc(pos p); +creature *dormantMonsterAtLoc(pos p); +pos perimeterCoords(short n); +boolean monsterBlinkToPreferenceMap(creature *monst, short **preferenceMap, boolean blinkUphill); +boolean monsterSummons(creature *monst, boolean alwaysUse); +boolean resurrectAlly(const short x, const short y); +void unAlly(creature *monst); +boolean monsterFleesFrom(creature *monst, creature *defender); +void monstersTurn(creature *monst); +boolean getRandomMonsterSpawnLocation(short *x, short *y); +void spawnPeriodicHorde(); +void clearStatus(creature *monst); +void moralAttack(creature *attacker, creature *defender); +short runicWeaponChance(item *theItem, boolean customEnchantLevel, fixpt enchantLevel); +void magicWeaponHit(creature *defender, item *theItem, boolean backstabbed); +void disentangle(creature *monst); +void teleport(creature *monst, short x, short y, boolean respectTerrainAvoidancePreferences); +void chooseNewWanderDestination(creature *monst); +boolean canPass(creature *mover, creature *blocker); +boolean isPassableOrSecretDoor(short x, short y); +boolean knownToPlayerAsPassableOrSecretDoor(short x, short y); +void setMonsterLocation(creature *monst, short newX, short newY); +boolean moveMonster(creature *monst, short dx, short dy); +unsigned long burnedTerrainFlagsAtLoc(short x, short y); +unsigned long discoveredTerrainFlagsAtLoc(short x, short y); +boolean monsterAvoids(creature *monst, pos p); +short distanceBetween(pos loc1, pos loc2); +void alertMonster(creature *monst); +void wakeUp(creature *monst); +boolean monsterRevealed(creature *monst); +boolean monsterHiddenBySubmersion(const creature *monst, const creature *observer); +boolean monsterIsHidden(const creature *monst, const creature *observer); +boolean canSeeMonster(creature *monst); +boolean canDirectlySeeMonster(creature *monst); +void monsterName(char *buf, creature *monst, boolean includeArticle); +boolean monsterIsInClass(const creature *monst, const short monsterClass); +boolean chooseTarget(pos *returnLoc, short maxDistance, boolean stopAtTarget, boolean autoTarget, boolean targetAllies, const bolt *theBolt, const color *trajectoryColor); +fixpt strengthModifier(item *theItem); +fixpt netEnchant(item *theItem); +short hitProbability(creature *attacker, creature *defender); +boolean attackHit(creature *attacker, creature *defender); +void applyArmorRunicEffect(char returnString[DCOLS], creature *attacker, short *damage, boolean melee); +void processStaggerHit(creature *attacker, creature *defender); +boolean attack(creature *attacker, creature *defender, boolean lungeAttack); +void inflictLethalDamage(creature *attacker, creature *defender); +boolean inflictDamage(creature *attacker, creature *defender, short damage, const color *flashColor, boolean ignoresProtectionShield); +void addPoison(creature *monst, short totalDamage, short concentrationIncrement); +void killCreature(creature *decedent, boolean administrativeDeath); +void buildHitList(creature **hitList, const creature *attacker, creature *defender, const boolean sweep); +void addScentToCell(short x, short y, short distance); +void populateItems(short upstairsX, short upstairsY); +item *placeItem(item *theItem, short x, short y); +void removeItemFrom(short x, short y); +void pickUpItemAt(short x, short y); +item *addItemToPack(item *theItem); +void aggravateMonsters(short distance, short x, short y, const color *flashColor); +short getLineCoordinates(pos listOfCoordinates[], const pos originLoc, const pos targetLoc, const bolt *theBolt); +void getImpactLoc(pos *returnLoc, const pos originLoc, const pos targetLoc, const short maxDistance, const boolean returnLastEmptySpace, const bolt *theBolt); +boolean negate(creature *monst); +short monsterAccuracyAdjusted(const creature *monst); +fixpt monsterDamageAdjustmentAmount(const creature *monst); +short monsterDefenseAdjusted(const creature *monst); +void weaken(creature *monst, short maxDuration); +void slow(creature *monst, short turns); +void haste(creature *monst, short turns); +void heal(creature *monst, short percent, boolean panacea); +boolean projectileReflects(creature *attacker, creature *defender); +short reflectBolt(short targetX, short targetY, pos listOfCoordinates[], short kinkCell, boolean retracePath); +void checkForMissingKeys(short x, short y); +enum boltEffects boltEffectForItem(item *theItem); +enum boltType boltForItem(item *theItem); +boolean zap(pos originLoc, pos targetLoc, bolt *theBolt, boolean hideDetails, boolean reverseBoltDir); +boolean nextTargetAfter(short *returnX, short *returnY, short targetX, short targetY, boolean targetEnemies, boolean targetAllies, boolean targetItems, boolean targetTerrain, boolean requireOpenPath, boolean reverseDirection); +boolean moveCursor(boolean *targetConfirmed, boolean *canceled, boolean *tabKey, pos *targetLoc, rogueEvent *event, buttonState *state, boolean colorsDance, boolean keysMoveCursor, boolean targetCanLeaveMap); +void identifyItemKind(item *theItem); +void autoIdentify(item *theItem); +short numberOfItemsInPack(); +char nextAvailableInventoryCharacter(); +void checkForDisenchantment(item *theItem); +void updateFloorItems(); +void itemKindName(item *theItem, char *kindName); +void itemRunicName(item *theItem, char *runicName); +void itemName(item *theItem, char *root, boolean includeDetails, boolean includeArticle, const color *baseColor); +int itemKindCount(enum itemCategory category, int magicPolarity); +char displayInventory(unsigned short categoryMask, unsigned long requiredFlags, unsigned long forbiddenFlags, boolean waitForAcknowledge, boolean includeButtons); +short numberOfMatchingPackItems(unsigned short categoryMask, unsigned long requiredFlags, unsigned long forbiddenFlags, boolean displayErrors); +void clearInventory(char keystroke); +item *initializeItem(); +item *generateItem(unsigned short theCategory, short theKind); +short chooseKind(const itemTable *theTable, short numKinds); +item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind); +void updateEncumbrance(); +short displayedArmorValue(); +short armorValueIfUnenchanted(item *theItem); +void strengthCheck(item *theItem, boolean noisy); +void recalculateEquipmentBonuses(); +boolean equipItem(item *theItem, boolean force, item *unequipHint); +void equip(item *theItem); +item *keyInPackFor(short x, short y); +item *keyOnTileAt(short x, short y); +void unequip(item *theItem); +void drop(item *theItem); +void findAlternativeHomeFor(creature *monst, short *x, short *y, boolean chooseRandomly); +boolean getQualifyingLocNear(pos *loc, short x, short y, boolean hallwaysAllowed, char blockingMap[DCOLS][DROWS], unsigned long forbiddenTerrainFlags, unsigned long forbiddenMapFlags, boolean forbidLiquid, boolean deterministic); +boolean getQualifyingGridLocNear(pos *loc, short x, short y, boolean grid[DCOLS][DROWS], boolean deterministic); + +// Grid operations +short **allocGrid(); +void freeGrid(short **array); +void copyGrid(short **to, short **from); +void fillGrid(short **grid, short fillValue); +void hiliteGrid(short **grid, const color *hiliteColor, short hiliteStrength); +void findReplaceGrid(short **grid, short findValueMin, short findValueMax, short fillValue); +short floodFillGrid(short **grid, short x, short y, short eligibleValueMin, short eligibleValueMax, short fillValue); +void drawRectangleOnGrid(short **grid, short x, short y, short width, short height, short value); +void drawCircleOnGrid(short **grid, short x, short y, short radius, short value); +void getTerrainGrid(short **grid, short value, unsigned long terrainFlags, unsigned long mapFlags); +void getTMGrid(short **grid, short value, unsigned long TMflags); +short validLocationCount(short **grid, short validValue); +void randomLocationInGrid(short **grid, short *x, short *y, short validValue); +boolean getQualifyingPathLocNear(short *retValX, short *retValY, short x, short y, boolean hallwaysAllowed, unsigned long blockingTerrainFlags, unsigned long blockingMapFlags, unsigned long forbiddenTerrainFlags, + unsigned long forbiddenMapFlags, boolean deterministic); +void createBlobOnGrid(short **grid, short *retMinX, short *retMinY, short *retWidth, short *retHeight, short roundCount, short minBlobWidth, short minBlobHeight, short maxBlobWidth, short maxBlobHeight, short percentSeeded, + char birthParameters[9], char survivalParameters[9]); + +void checkForContinuedLeadership(creature *monst); +void demoteMonsterFromLeadership(creature *monst); +void toggleMonsterDormancy(creature *monst); +void monsterDetails(char buf[], creature *monst); +void makeMonsterDropItem(creature *monst); +void throwCommand(item *theItem, boolean autoThrow); +void relabel(item *theItem); +void swapLastEquipment(); +void apply(item *theItem, boolean recordCommands); +boolean itemCanBeCalled(item *theItem); +void call(item *theItem); +short chooseVorpalEnemy(); +void describeMonsterClass(char *buf, const short classID, boolean conjunctionAnd); +void identify(item *theItem); +void updateIdentifiableItem(item *theItem); +void updateIdentifiableItems(); +void readScroll(item *theItem); +void updateRingBonuses(); +void updatePlayerRegenerationDelay(); +boolean removeItemFromChain(item *theItem, item *theChain); +void addItemToChain(item *theItem, item *theChain); +void drinkPotion(item *theItem); +item *promptForItemOfType(unsigned short category, unsigned long requiredFlags, unsigned long forbiddenFlags, char *prompt, boolean allowInventoryActions); +item *itemOfPackLetter(char letter); +boolean unequipItem(item *theItem, boolean force); +short magicCharDiscoverySuffix(short category, short kind); +int itemMagicPolarity(item *theItem); +item *itemAtLoc(short x, short y); +item *dropItem(item *theItem); +itemTable *tableForItemCategory(enum itemCategory theCat); +boolean isVowelish(char *theChar); +short charmEffectDuration(short charmKind, short enchant); +short charmRechargeDelay(short charmKind, short enchant); +boolean itemIsCarried(item *theItem); +void itemDetails(char *buf, item *theItem); +void deleteItem(item *theItem); +void shuffleFlavors(); +unsigned long itemValue(item *theItem); +short strLenWithoutEscapes(const char *str); +void combatMessage(char *theMsg, const color *theColor); +void displayCombatText(); +void flashMonster(creature *monst, const color *theColor, short strength); + +boolean paintLight(const lightSource *theLight, short x, short y, boolean isMinersLight, boolean maintainShadows); +void backUpLighting(short lights[DCOLS][DROWS][3]); +void restoreLighting(short lights[DCOLS][DROWS][3]); +void updateLighting(); +boolean playerInDarkness(); +flare *newFlare(const lightSource *light, short x, short y, short changePerFrame, short limit); +void createFlare(short x, short y, enum lightType lightIndex); +void animateFlares(flare **flares, short count); +void deleteAllFlares(); +void demoteVisibility(); +void discoverCell(const short x, const short y); +void updateVision(boolean refreshDisplay); +void burnItem(item *theItem); +void activateMachine(short machineNumber); +boolean circuitBreakersPreventActivation(short machineNumber); +void promoteTile(short x, short y, enum dungeonLayers layer, boolean useFireDF); +void autoPlayLevel(boolean fastForward); +void updateClairvoyance(); +short scentDistance(short x1, short y1, short x2, short y2); +short armorStealthAdjustment(item *theArmor); +short currentStealthRange(); + +void initRecording(); +void flushBufferToFile(); +void fillBufferFromFile(); +void recordEvent(rogueEvent *event); +void recallEvent(rogueEvent *event); +void pausePlayback(); +void displayAnnotation(); +boolean loadSavedGame(); +void switchToPlaying(); +void recordKeystroke(int keystroke, boolean controlKey, boolean shiftKey); +void cancelKeystroke(); +void recordKeystrokeSequence(unsigned char *commandSequence); +void recordMouseClick(short x, short y, boolean controlKey, boolean shiftKey); +void OOSCheck(unsigned long x, short numberOfBytes); +void RNGCheck(); +boolean executePlaybackInput(rogueEvent *recordingInput); +void getAvailableFilePath(char *filePath, const char *defaultPath, const char *suffix); +boolean characterForbiddenInFilename(const char theChar); +void saveGame(); +void saveGameNoPrompt(); +void saveRecording(char *filePath); +void saveRecordingNoPrompt(char *filePath); +void parseFile(); +void RNGLog(char *message); + +short wandDominate(creature *monst); +short staffDamageLow(fixpt enchant); +short staffDamageHigh(fixpt enchant); +short staffDamage(fixpt enchant); +int staffPoison(fixpt enchant); +short staffBlinkDistance(fixpt enchant); +short staffHasteDuration(fixpt enchant); +short staffBladeCount(fixpt enchant); +short staffDiscordDuration(fixpt enchant); +int staffProtection(fixpt enchant); +short staffEntrancementDuration(fixpt enchant); +fixpt ringWisdomMultiplier(fixpt enchant); +short charmHealing(fixpt enchant); +int charmProtection(fixpt enchant); +short charmShattering(fixpt enchant); +short charmGuardianLifespan(fixpt enchant); +short charmNegationRadius(fixpt enchant); +short weaponParalysisDuration(fixpt enchant); +short weaponConfusionDuration(fixpt enchant); +short weaponForceDistance(fixpt enchant); +short weaponSlowDuration(fixpt enchant); +short weaponImageCount(fixpt enchant); +short weaponImageDuration(fixpt enchant); +short armorReprisalPercent(fixpt enchant); +short armorAbsorptionMax(fixpt enchant); +short armorImageCount(fixpt enchant); +short reflectionChance(fixpt enchant); +long turnsForFullRegenInThousandths(fixpt bonus); +fixpt damageFraction(fixpt netEnchant); +fixpt accuracyFraction(fixpt netEnchant); +fixpt defenseFraction(fixpt netDefense); + +void checkForDungeonErrors(); + +boolean dialogChooseFile(char *path, const char *suffix, const char *prompt); +void dialogCreateItemOrMonster(); +int quitImmediately(); +void dialogAlert(char *message); +void mainBrogueJunction(); +void printSeedCatalog(uint64_t startingSeed, uint64_t numberOfSeedsToScan, unsigned int scanThroughDepth, boolean isCsvFormat); + +void initializeButton(brogueButton *button); +void drawButtonsInState(buttonState *state); +void initializeButtonState(buttonState *state, brogueButton *buttons, short buttonCount, short winX, short winY, short winWidth, short winHeight); +short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *event); +short smoothHiliteGradient(const short currentXValue, const short maxXValue); +void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDisplayBuffer dbuf[COLS][ROWS]); +short buttonInputLoop(brogueButton *buttons, short buttonCount, short winX, short winY, short winWidth, short winHeight, rogueEvent *returnEvent); + +void dijkstraScan(short **distanceMap, short **costMap, boolean useDiagonals); #if defined __cplusplus } diff --git a/src/brogue/RogueMain.c b/src/brogue/RogueMain.c index 1e40a121..e3e58a17 100644 --- a/src/brogue/RogueMain.c +++ b/src/brogue/RogueMain.c @@ -44,8 +44,7 @@ void executeEvent(rogueEvent *theEvent) { rogue.playbackBetweenTurns = false; if (theEvent->eventType == KEYSTROKE) { executeKeystroke(theEvent->param1, theEvent->controlKey, theEvent->shiftKey); - } else if (theEvent->eventType == MOUSE_UP - || theEvent->eventType == RIGHT_MOUSE_UP) { + } else if (theEvent->eventType == MOUSE_UP || theEvent->eventType == RIGHT_MOUSE_UP) { executeMouseClick(theEvent); } } @@ -65,14 +64,7 @@ boolean fileExists(const char *pathname) { // Otherwise, return false. boolean chooseFile(char *path, char *prompt, char *defaultName, char *suffix) { - if (getInputTextString(path, - prompt, - min(DCOLS-25, BROGUE_FILENAME_MAX - strlen(suffix)), - defaultName, - suffix, - TEXT_INPUT_FILENAME, - false) - && path[0] != '\0') { + if (getInputTextString(path, prompt, min(DCOLS - 25, BROGUE_FILENAME_MAX - strlen(suffix)), defaultName, suffix, TEXT_INPUT_FILENAME, false) && path[0] != '\0') { strcat(path, suffix); return true; @@ -96,9 +88,9 @@ boolean openFile(const char *path) { // Clip off the suffix. strcpy(buf, path); - for (i = strlen(path); buf[i] != '.' && i > 0; i--) continue; - if (buf[i] == '.' - && i + strlen(ANNOTATION_SUFFIX) < BROGUE_FILENAME_MAX) { + for (i = strlen(path); buf[i] != '.' && i > 0; i--) + continue; + if (buf[i] == '.' && i + strlen(ANNOTATION_SUFFIX) < BROGUE_FILENAME_MAX) { buf[i] = '\0'; // Snip! strcat(buf, ANNOTATION_SUFFIX); @@ -114,24 +106,24 @@ boolean openFile(const char *path) { void benchmark() { short i, j, k; - const color sparklesauce = {10, 0, 20, 60, 40, 100, 30, true}; + const color sparklesauce = {10, 0, 20, 60, 40, 100, 30, true}; enum displayGlyph theChar; - unsigned long initialTime = (unsigned long) time(NULL); - for (k=0; k<500; k++) { - for (i=0; ideepestLevel+1)); + levels = malloc(sizeof(levelData) * (gameConst->deepestLevel + 1)); levels[0].upStairsLoc.x = (DCOLS - 1) / 2 - 1; levels[0].upStairsLoc.y = DROWS - 2; @@ -221,36 +213,38 @@ void initializeRogue(uint64_t seed) { resetDFMessageEligibility(); // initialize the levels list - for (i=0; ideepestLevel+1; i++) { + for (i = 0; i < gameConst->deepestLevel + 1; i++) { if (rogue.seed >> 32) { // generate a 64-bit seed levels[i].levelSeed = rand_64bits(); } else { // backward-compatible seed - levels[i].levelSeed = (unsigned long) rand_range(0, 9999); - levels[i].levelSeed += (unsigned long) 10000 * rand_range(0, 9999); + levels[i].levelSeed = (unsigned long)rand_range(0, 9999); + levels[i].levelSeed += (unsigned long)10000 * rand_range(0, 9999); } if (levels[i].levelSeed == 0) { // seed 0 is not acceptable levels[i].levelSeed = i + 1; } - levels[i].monsters = createCreatureList();; - levels[i].dormantMonsters = createCreatureList();; + levels[i].monsters = createCreatureList(); + ; + levels[i].dormantMonsters = createCreatureList(); + ; levels[i].items = NULL; levels[i].scentMap = NULL; levels[i].visited = false; - levels[i].playerExitedVia = (pos){ .x = 0, .y = 0 }; + levels[i].playerExitedVia = (pos){.x = 0, .y = 0}; do { levels[i].downStairsLoc.x = rand_range(1, DCOLS - 2); levels[i].downStairsLoc.y = rand_range(1, DROWS - 2); } while (distanceBetween(levels[i].upStairsLoc, levels[i].downStairsLoc) < DCOLS / 3); if (i < gameConst->deepestLevel) { - levels[i+1].upStairsLoc.x = levels[i].downStairsLoc.x; - levels[i+1].upStairsLoc.y = levels[i].downStairsLoc.y; + levels[i + 1].upStairsLoc.x = levels[i].downStairsLoc.x; + levels[i + 1].upStairsLoc.y = levels[i].downStairsLoc.y; } } // initialize the waypoints list - for (i=0; inextItem = NULL; - packItems = (item *) malloc(sizeof(item)); + packItems = (item *)malloc(sizeof(item)); memset(packItems, '\0', sizeof(item)); packItems->nextItem = NULL; - monsterItemsHopper = (item *) malloc(sizeof(item)); + monsterItemsHopper = (item *)malloc(sizeof(item)); memset(monsterItemsHopper, '\0', sizeof(item)); monsterItemsHopper->nextItem = NULL; @@ -311,10 +305,10 @@ void initializeRogue(uint64_t seed) { dormantMonsters = &levels[0].dormantMonsters; purgatory = createCreatureList(); - scentMap = NULL; - safetyMap = allocGrid(); - allySafetyMap = allocGrid(); - chokeMap = allocGrid(); + scentMap = NULL; + safetyMap = allocGrid(); + allySafetyMap = allocGrid(); + chokeMap = allocGrid(); rogue.mapToSafeTerrain = allocGrid(); @@ -380,8 +374,7 @@ void initializeRogue(uint64_t seed) { rogue.minersLight = lightCatalog[MINERS_LIGHT]; - rogue.clairvoyance = rogue.regenerationBonus - = rogue.stealthBonus = rogue.transference = rogue.wisdomBonus = rogue.reaping = 0; + rogue.clairvoyance = rogue.regenerationBonus = rogue.stealthBonus = rogue.transference = rogue.wisdomBonus = rogue.reaping = 0; rogue.lightMultiplier = 1; theItem = generateItem(FOOD, RATION); @@ -494,7 +487,6 @@ void initializeRogue(uint64_t seed) { theItem->charges = 300; identify(theItem); theItem = addItemToPack(theItem); - } clearMessageArchive(); blackOutScreen(); @@ -505,7 +497,7 @@ void initializeRogue(uint64_t seed) { void updateColors() { short i; - for (i=0; iamuletLevel))); } @@ -528,26 +520,26 @@ void startLevel(short oldLevelNumber, short stairDirection) { synchronizePlayerTimeState(); - rogue.updatedSafetyMapThisTurn = false; - rogue.updatedAllySafetyMapThisTurn = false; - rogue.updatedMapToSafeTerrainThisTurn = false; + rogue.updatedSafetyMapThisTurn = false; + rogue.updatedAllySafetyMapThisTurn = false; + rogue.updatedMapToSafeTerrainThisTurn = false; rogue.cursorLoc = INVALID_POS; rogue.lastTarget = NULL; connectingStairsDiscovered = (pmapAt(rogue.downLoc)->flags & (DISCOVERED | MAGIC_MAPPED) ? true : false); if (stairDirection == 0) { // fallen - levels[oldLevelNumber-1].playerExitedVia = (pos){ .x = player.loc.x, .y = player.loc.y }; + levels[oldLevelNumber - 1].playerExitedVia = (pos){.x = player.loc.x, .y = player.loc.y}; } if (oldLevelNumber != rogue.depthLevel) { px = player.loc.x; py = player.loc.y; if (cellHasTerrainFlag(player.loc.x, player.loc.y, T_AUTO_DESCENT)) { - for (i=0; i<8; i++) { - if (!cellHasTerrainFlag(player.loc.x+nbDirs[i][0], player.loc.y+nbDirs[i][1], (T_PATHING_BLOCKER))) { - px = player.loc.x+nbDirs[i][0]; - py = player.loc.y+nbDirs[i][1]; + for (i = 0; i < 8; i++) { + if (!cellHasTerrainFlag(player.loc.x + nbDirs[i][0], player.loc.y + nbDirs[i][1], (T_PATHING_BLOCKER))) { + px = player.loc.x + nbDirs[i][0]; + py = player.loc.y + nbDirs[i][1]; break; } } @@ -561,17 +553,10 @@ void startLevel(short oldLevelNumber, short stairDirection) { creature *monst = nextCreature(&it); x = monst->loc.x; y = monst->loc.y; - if (((monst->creatureState == MONSTER_TRACKING_SCENT && (stairDirection != 0 || monst->status[STATUS_LEVITATING])) - || monst->creatureState == MONSTER_ALLY || monst == rogue.yendorWarden) + if (((monst->creatureState == MONSTER_TRACKING_SCENT && (stairDirection != 0 || monst->status[STATUS_LEVITATING])) || monst->creatureState == MONSTER_ALLY || monst == rogue.yendorWarden) && (stairDirection != 0 || monst->currentHP > 10 || monst->status[STATUS_LEVITATING]) - && ((flying != 0) == ((monst->status[STATUS_LEVITATING] != 0) - || cellHasTerrainFlag(x, y, T_PATHING_BLOCKER) - || cellHasTerrainFlag(px, py, T_AUTO_DESCENT))) - && !(monst->bookkeepingFlags & MB_CAPTIVE) - && !(monst->info.flags & (MONST_WILL_NOT_USE_STAIRS | MONST_RESTRICTED_TO_LIQUID)) - && !(cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) - && !monst->status[STATUS_ENTRANCED] - && !monst->status[STATUS_PARALYZED] + && ((flying != 0) == ((monst->status[STATUS_LEVITATING] != 0) || cellHasTerrainFlag(x, y, T_PATHING_BLOCKER) || cellHasTerrainFlag(px, py, T_AUTO_DESCENT))) && !(monst->bookkeepingFlags & MB_CAPTIVE) + && !(monst->info.flags & (MONST_WILL_NOT_USE_STAIRS | MONST_RESTRICTED_TO_LIQUID)) && !(cellHasTerrainFlag(x, y, T_OBSTRUCTS_PASSABILITY)) && !monst->status[STATUS_ENTRANCED] && !monst->status[STATUS_PARALYZED] && (mapToStairs[monst->loc.x][monst->loc.y] < 30000 || monst->creatureState == MONSTER_ALLY || monst == rogue.yendorWarden)) { monst->status[STATUS_ENTERS_LEVEL_IN] = clamp(mapToStairs[monst->loc.x][monst->loc.y] * monst->movementSpeed / 100 + 1, 1, 150); @@ -601,10 +586,10 @@ void startLevel(short oldLevelNumber, short stairDirection) { monst->mapToMe = NULL; } } - levels[oldLevelNumber-1].items = floorItems->nextItem; + levels[oldLevelNumber - 1].items = floorItems->nextItem; - for (i=0; inextItem = levels[rogue.depthLevel-1].items; + monsters = &levels[rogue.depthLevel - 1].monsters; + dormantMonsters = &levels[rogue.depthLevel - 1].dormantMonsters; + floorItems->nextItem = levels[rogue.depthLevel - 1].items; - levels[rogue.depthLevel-1].items = NULL; + levels[rogue.depthLevel - 1].items = NULL; digDungeon(); initializeLevel(); @@ -667,9 +652,7 @@ void startLevel(short oldLevelNumber, short stairDirection) { // If we somehow failed to generate the amulet altar, // just toss an amulet in there somewhere. // It'll be fiiine! - if (rogue.depthLevel == gameConst->amuletLevel - && !numberOfMatchingPackItems(AMULET, 0, 0, false) - && levels[rogue.depthLevel-1].visited == false) { + if (rogue.depthLevel == gameConst->amuletLevel && !numberOfMatchingPackItems(AMULET, 0, 0, false) && levels[rogue.depthLevel - 1].visited == false) { for (theItem = floorItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { if (theItem->category & AMULET) { @@ -678,8 +661,7 @@ void startLevel(short oldLevelNumber, short stairDirection) { } for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); - if (monst->carriedItem - && (monst->carriedItem->category & AMULET)) { + if (monst->carriedItem && (monst->carriedItem->category & AMULET)) { theItem = monst->carriedItem; break; @@ -693,7 +675,7 @@ void startLevel(short oldLevelNumber, short stairDirection) { // re-seed the RNG seedRandomGenerator(oldSeed); - //logLevel(); + // logLevel(); // Simulate 50 turns so the level is broken in (swamp gas accumulating, brimstone percolating, etc.). timeAway = 50; @@ -704,8 +686,8 @@ void startLevel(short oldLevelNumber, short stairDirection) { scentMap = levels[rogue.depthLevel - 1].scentMap; timeAway = clamp(0, rogue.absoluteTurnNumber - levels[rogue.depthLevel - 1].awaySince, 30000); - for (i=0; inextItem = levels[rogue.depthLevel - 1].items; - levels[rogue.depthLevel-1].items = NULL; + levels[rogue.depthLevel - 1].items = NULL; for (theItem = floorItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { restoreItem(theItem); } - } // Simulate the environment! @@ -763,8 +744,8 @@ void startLevel(short oldLevelNumber, short stairDirection) { rogue.ticksTillUpdateEnvironment += 100; } - if (!levels[rogue.depthLevel-1].visited) { - levels[rogue.depthLevel-1].visited = true; + if (!levels[rogue.depthLevel - 1].visited) { + levels[rogue.depthLevel - 1].visited = true; if (rogue.depthLevel == gameConst->amuletLevel) { messageWithColor(levelFeelings[0].message, levelFeelings[0].color, 0); } else if (rogue.depthLevel == gameConst->deepestLevel) { @@ -775,16 +756,12 @@ void startLevel(short oldLevelNumber, short stairDirection) { // Position the player. pos loc; if (stairDirection == 0) { // fell into the level - getQualifyingLocNear(&loc, player.loc.x, player.loc.y, true, 0, - (T_PATHING_BLOCKER & ~T_IS_DEEP_WATER), - (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), false, false); + getQualifyingLocNear(&loc, player.loc.x, player.loc.y, true, 0, (T_PATHING_BLOCKER & ~T_IS_DEEP_WATER), (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), false, false); if (cellHasTerrainFlag(loc.x, loc.y, T_IS_DEEP_WATER)) { // Fell into deep water... can we swim out of it? pos dryLoc; - getQualifyingLocNear(&dryLoc, player.loc.x, player.loc.y, true, 0, - (T_PATHING_BLOCKER), - (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), false, false); + getQualifyingLocNear(&dryLoc, player.loc.x, player.loc.y, true, 0, (T_PATHING_BLOCKER), (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), false, false); short swimDistance = pathingDistance(loc.x, loc.y, dryLoc.x, dryLoc.y, T_PATHING_BLOCKER & ~T_IS_DEEP_WATER); if (swimDistance == 30000) { @@ -801,20 +778,14 @@ void startLevel(short oldLevelNumber, short stairDirection) { } placedPlayer = false; - for (dir=0; dir<4 && !placedPlayer; dir++) { + for (dir = 0; dir < 4 && !placedPlayer; dir++) { loc = posNeighborInDirection(player.loc, dir); - if (!cellHasTerrainFlag(loc.x, loc.y, T_PATHING_BLOCKER) - && !(pmapAt(loc)->flags & (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE))) { + if (!cellHasTerrainFlag(loc.x, loc.y, T_PATHING_BLOCKER) && !(pmapAt(loc)->flags & (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE))) { placedPlayer = true; } } if (!placedPlayer) { - getQualifyingPathLocNear(&loc.x, &loc.y, - player.loc.x, player.loc.y, - true, - T_DIVIDES_LEVEL, 0, - T_PATHING_BLOCKER, (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), - false); + getQualifyingPathLocNear(&loc.x, &loc.y, player.loc.x, player.loc.y, true, T_DIVIDES_LEVEL, 0, T_PATHING_BLOCKER, (HAS_MONSTER | HAS_ITEM | HAS_STAIRS | IS_IN_MACHINE), false); } } player.loc = loc; @@ -822,16 +793,15 @@ void startLevel(short oldLevelNumber, short stairDirection) { pmapAt(player.loc)->flags |= HAS_PLAYER; if (connectingStairsDiscovered) { - for (i = rogue.upLoc.x-1; i <= rogue.upLoc.x + 1; i++) { - for (j = rogue.upLoc.y-1; j <= rogue.upLoc.y + 1; j++) { + for (i = rogue.upLoc.x - 1; i <= rogue.upLoc.x + 1; i++) { + for (j = rogue.upLoc.y - 1; j <= rogue.upLoc.y + 1; j++) { if (coordinatesAreInMap(i, j)) { discoverCell(i, j); } } } } - if (cellHasTerrainFlag(player.loc.x, player.loc.y, T_IS_DEEP_WATER) && !player.status[STATUS_LEVITATING] - && !cellHasTerrainFlag(player.loc.x, player.loc.y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY))) { + if (cellHasTerrainFlag(player.loc.x, player.loc.y, T_IS_DEEP_WATER) && !player.status[STATUS_LEVITATING] && !cellHasTerrainFlag(player.loc.x, player.loc.y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY))) { rogue.inWater = true; } @@ -841,8 +811,7 @@ void startLevel(short oldLevelNumber, short stairDirection) { fillGrid(mapToStairs, 0); fillGrid(mapToPit, 0); calculateDistances(mapToStairs, player.loc.x, player.loc.y, T_PATHING_BLOCKER, NULL, true, true); - calculateDistances(mapToPit, levels[rogue.depthLevel-1].playerExitedVia.x, - levels[rogue.depthLevel-1].playerExitedVia.y, T_PATHING_BLOCKER, NULL, true, true); + calculateDistances(mapToPit, levels[rogue.depthLevel - 1].playerExitedVia.x, levels[rogue.depthLevel - 1].playerExitedVia.y, T_PATHING_BLOCKER, NULL, true, true); for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); restoreMonster(monst, mapToStairs, mapToPit); @@ -870,7 +839,8 @@ void startLevel(short oldLevelNumber, short stairDirection) { } RNGCheck(); flushBufferToFile(); - deleteAllFlares(); // So discovering something on the same turn that you fall down a level doesn't flash stuff on the previous level. + deleteAllFlares(); // So discovering something on the same turn that you fall down a level doesn't flash stuff on + // the previous level. hideCursor(); } @@ -904,10 +874,7 @@ static void removeDeadMonstersFromList(creatureList *list) { next = next->nextCreature; if (decedent->bookkeepingFlags & MB_HAS_DIED) { removeCreature(list, decedent); - if (decedent->leader == &player - && !(decedent->info.flags & MONST_INANIMATE) - && (decedent->bookkeepingFlags & MB_HAS_SOUL) - && !(decedent->bookkeepingFlags & MB_ADMINISTRATIVE_DEATH)) { + if (decedent->leader == &player && !(decedent->info.flags & MONST_INANIMATE) && (decedent->bookkeepingFlags & MB_HAS_SOUL) && !(decedent->bookkeepingFlags & MB_ADMINISTRATIVE_DEATH)) { // Unset flag, since the purgatory list should be iterable. decedent->bookkeepingFlags &= ~MB_HAS_DIED; @@ -940,7 +907,7 @@ void freeEverything() { freeGlobalDynamicGrid(&rogue.mapToShore); freeGlobalDynamicGrid(&rogue.mapToSafeTerrain); - for (i=0; ideepestLevel+1; i++) { + for (i = 0; i < gameConst->deepestLevel + 1; i++) { freeCreatureList(&levels[i].monsters); freeCreatureList(&levels[i].dormantMonsters); @@ -972,7 +939,7 @@ void freeEverything() { deleteItem(theItem); } monsterItemsHopper = NULL; - for (i=0; iquantity; } if (theItem->category == AMULET && superVictory) { - plotCharToBuffer(G_AMULET, (windowpos){ mapToWindowX(2), min(ROWS-1, i + 1) }, &yellow, &black, dbuf); - printString("The Birthright of Yendor", mapToWindowX(4), min(ROWS-1, i + 1), &itemMessageColor, &black, dbuf); + plotCharToBuffer(G_AMULET, (windowpos){mapToWindowX(2), min(ROWS - 1, i + 1)}, &yellow, &black, dbuf); + printString("The Birthright of Yendor", mapToWindowX(4), min(ROWS - 1, i + 1), &itemMessageColor, &black, dbuf); sprintf(buf, "%li", max(0, itemValue(theItem) * 2)); - printString(buf, mapToWindowX(60), min(ROWS-1, i + 1), &itemMessageColor, &black, dbuf); + printString(buf, mapToWindowX(60), min(ROWS - 1, i + 1), &itemMessageColor, &black, dbuf); totalValue += max(0, itemValue(theItem) * 2); i++; } else { @@ -1221,12 +1182,12 @@ void victory(boolean superVictory) { itemName(theItem, buf, true, true, &white); upperCase(buf); - plotCharToBuffer(theItem->displayChar, (windowpos){ mapToWindowX(2), min(ROWS-1, i + 1) }, &yellow, &black, dbuf); - printString(buf, mapToWindowX(4), min(ROWS-1, i + 1), &white, &black, dbuf); + plotCharToBuffer(theItem->displayChar, (windowpos){mapToWindowX(2), min(ROWS - 1, i + 1)}, &yellow, &black, dbuf); + printString(buf, mapToWindowX(4), min(ROWS - 1, i + 1), &white, &black, dbuf); if (itemValue(theItem) > 0) { sprintf(buf, "%li", max(0, itemValue(theItem))); - printString(buf, mapToWindowX(60), min(ROWS-1, i + 1), &itemMessageColor, &black, dbuf); + printString(buf, mapToWindowX(60), min(ROWS - 1, i + 1), &itemMessageColor, &black, dbuf); } totalValue += max(0, itemValue(theItem)); @@ -1234,11 +1195,11 @@ void victory(boolean superVictory) { } } i++; - printString("TOTAL:", mapToWindowX(2), min(ROWS-1, i + 1), &lightBlue, &black, dbuf); + printString("TOTAL:", mapToWindowX(2), min(ROWS - 1, i + 1), &lightBlue, &black, dbuf); sprintf(buf, "%li", totalValue); - printString(buf, mapToWindowX(60), min(ROWS-1, i + 1), &lightBlue, &black, dbuf); + printString(buf, mapToWindowX(60), min(ROWS - 1, i + 1), &lightBlue, &black, dbuf); - funkyFade(dbuf, &white, 0, 120, COLS/2, ROWS/2, true); + funkyFade(dbuf, &white, 0, 120, COLS / 2, ROWS / 2, true); displayMoreSign(); // @@ -1334,7 +1295,7 @@ void enableEasyMode() { // takes a flag of the form Fl(n) and returns n short unflag(unsigned long flag) { short i; - for (i=0; i<32; i++) { + for (i = 0; i < 32; i++) { if (flag >> i == 1) { return i; } diff --git a/src/brogue/SeedCatalog.c b/src/brogue/SeedCatalog.c index aea0e6fe..cc1d3c42 100644 --- a/src/brogue/SeedCatalog.c +++ b/src/brogue/SeedCatalog.c @@ -24,22 +24,22 @@ #include "GlobalsBase.h" #include "Globals.h" -#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" -#define NO_ENCHANTMENT_STRING "" -#define NO_RUNIC_STRING "" -#define NO_VAULT_STRING "" -#define NO_OPENS_VAULT_STRING "" -#define NO_CARRIED_BY_MONSTER_STRING "" -#define NO_ALLY_STATUS_STRING "" -#define NO_MUTATION_STRING "" - -static void printSeedCatalogCsvLine(uint64_t seed, short depth, short quantity, char categoryName[50], char kindName[50], - char enchantment[50], char runicName[50], char vaultNumber[10], char opensVaultNumber[10], - char carriedByMonsterName[50], char allyStatusName[20], char mutationName[100]){ - - printf("%s,%llu,%i,%i,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", gameConst->dungeonVersionString, (unsigned long long) seed, depth, quantity, categoryName, - kindName, enchantment, runicName, vaultNumber, opensVaultNumber, carriedByMonsterName, allyStatusName, - mutationName); +#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" +#define NO_ENCHANTMENT_STRING "" +#define NO_RUNIC_STRING "" +#define NO_VAULT_STRING "" +#define NO_OPENS_VAULT_STRING "" +#define NO_CARRIED_BY_MONSTER_STRING "" +#define NO_ALLY_STATUS_STRING "" +#define NO_MUTATION_STRING "" + +static void printSeedCatalogCsvLine(uint64_t seed, short depth, short quantity, char categoryName[50], char kindName[50], char enchantment[50], char runicName[50], char vaultNumber[10], char opensVaultNumber[10], + char carriedByMonsterName[50], char allyStatusName[20], char mutationName[100]) { + + printf("%s,%llu,%i,%i,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", gameConst->dungeonVersionString, (unsigned long long)seed, depth, quantity, categoryName, kindName, enchantment, runicName, vaultNumber, opensVaultNumber, carriedByMonsterName, + allyStatusName, mutationName); } static void getMonsterDetailedName(creature *theMonster, char *theMonsterName) { @@ -54,11 +54,11 @@ static void printSeedCatalogItem(item *theItem, creature *theMonster, boolean is char inGameItemName[500] = "", carriedByMonsterName[100] = "", vaultNumber[36] = "", opensVaultNumber[36] = ""; char categoryName[20] = "", kindName[50] = "", enchantment[5] = "", runicName[30] = "", mutationName[100] = ""; - if (isCsvFormat) { //for csv output we need the item name components: category, kind, enchantment, & runic + if (isCsvFormat) { // for csv output we need the item name components: category, kind, enchantment, & runic strcpy(categoryName, itemCategoryNames[unflag(theItem->category)]); itemKindName(theItem, kindName); itemRunicName(theItem, runicName); - if (theItem->category & (ARMOR | CHARM | RING | STAFF | WAND | WEAPON)) { //enchantable items + if (theItem->category & (ARMOR | CHARM | RING | STAFF | WAND | WEAPON)) { // enchantable items if (theItem->category == WAND) { sprintf(enchantment, "%i", theItem->charges); } else { @@ -66,10 +66,10 @@ static void printSeedCatalogItem(item *theItem, creature *theMonster, boolean is } } } else { - itemName(theItem, inGameItemName, true, true, NULL); //for standard output, use the in-game item name as base + itemName(theItem, inGameItemName, true, true, NULL); // for standard output, use the in-game item name as base } - if (theMonster != NULL) { //carried by monster + if (theMonster != NULL) { // carried by monster if (isCsvFormat) { sprintf(carriedByMonsterName, "%s", theMonster->info.monsterName); strcpy(mutationName, theMonster->mutationIndex >= 0 ? mutationCatalog[theMonster->mutationIndex].title : ""); @@ -80,13 +80,9 @@ static void printSeedCatalogItem(item *theItem, creature *theMonster, boolean is // vaultNumber if (pmapAt(theItem->loc)->machineNumber > 0) { - //not all machines are "vaults" so we need to exclude some. - if (pmapAt(theItem->loc)->layers[0] != ALTAR_SWITCH - && pmapAt(theItem->loc)->layers[0] != ALTAR_SWITCH_RETRACTING - && pmapAt(theItem->loc)->layers[0] != ALTAR_CAGE_RETRACTABLE - && pmapAt(theItem->loc)->layers[0] != ALTAR_INERT - && pmapAt(theItem->loc)->layers[0] != AMULET_SWITCH - && pmapAt(theItem->loc)->layers[0] != FLOOR) { + // not all machines are "vaults" so we need to exclude some. + if (pmapAt(theItem->loc)->layers[0] != ALTAR_SWITCH && pmapAt(theItem->loc)->layers[0] != ALTAR_SWITCH_RETRACTING && pmapAt(theItem->loc)->layers[0] != ALTAR_CAGE_RETRACTABLE && pmapAt(theItem->loc)->layers[0] != ALTAR_INERT + && pmapAt(theItem->loc)->layers[0] != AMULET_SWITCH && pmapAt(theItem->loc)->layers[0] != FLOOR) { sprintf(vaultNumber, isCsvFormat ? "%i" : " (vault %i)", pmapAt(theItem->loc)->machineNumber); } @@ -94,14 +90,11 @@ static void printSeedCatalogItem(item *theItem, creature *theMonster, boolean is // opensVaultNumber if (theItem->category == KEY && theItem->kind == KEY_DOOR) { - sprintf(opensVaultNumber, isCsvFormat ? "%i" : " (opens vault %i)", - pmap[theItem->keyLoc[0].x][theItem->keyLoc[0].y].machineNumber - 1); + sprintf(opensVaultNumber, isCsvFormat ? "%i" : " (opens vault %i)", pmap[theItem->keyLoc[0].x][theItem->keyLoc[0].y].machineNumber - 1); } if (isCsvFormat) { - printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, theItem->quantity, categoryName, kindName, enchantment, - runicName, vaultNumber, opensVaultNumber, carriedByMonsterName, NO_ALLY_STATUS_STRING, - mutationName); + printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, theItem->quantity, categoryName, kindName, enchantment, runicName, vaultNumber, opensVaultNumber, carriedByMonsterName, NO_ALLY_STATUS_STRING, mutationName); } else { upperCase(inGameItemName); if (theMonster != NULL) { @@ -118,23 +111,22 @@ static void printSeedCatalogMonster(creature *theMonster, boolean isCsvFormat) { strcpy(mutationName, theMonster->mutationIndex >= 0 ? mutationCatalog[theMonster->mutationIndex].title : ""); if (theMonster->bookkeepingFlags & MB_CAPTIVE) { - strcpy(categoryName,"ally"); + strcpy(categoryName, "ally"); if (cellHasTMFlag(theMonster->loc.x, theMonster->loc.y, TM_PROMOTES_WITH_KEY)) { strcpy(allyStatusName, isCsvFormat ? "caged" : "A caged "); } else { strcpy(allyStatusName, isCsvFormat ? "shackled" : "A shackled "); } } else if (theMonster->creatureState == MONSTER_ALLY) { - strcpy(categoryName,"ally"); + strcpy(categoryName, "ally"); strcpy(allyStatusName, isCsvFormat ? "allied" : "An allied "); } else { - strcpy(categoryName,"monster"); + strcpy(categoryName, "monster"); } if (isCsvFormat) { - printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, categoryName, theMonster->info.monsterName, - NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, NO_VAULT_STRING, NO_OPENS_VAULT_STRING, - NO_CARRIED_BY_MONSTER_STRING, allyStatusName, mutationName); + printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, categoryName, theMonster->info.monsterName, NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, NO_VAULT_STRING, NO_OPENS_VAULT_STRING, NO_CARRIED_BY_MONSTER_STRING, allyStatusName, + mutationName); } else { getMonsterDetailedName(theMonster, theMonsterName); printf(" %s%s\n", allyStatusName, theMonsterName); @@ -182,9 +174,7 @@ static void printSeedCatalogFloorGold(int gold, short piles, boolean isCsvFormat } else if (piles > 1) { sprintf(kindName, "gold pieces (%i piles)", piles); } - printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, gold, "gold", kindName, NO_ENCHANTMENT_STRING, - NO_RUNIC_STRING, NO_VAULT_STRING, NO_OPENS_VAULT_STRING, NO_CARRIED_BY_MONSTER_STRING, - NO_ALLY_STATUS_STRING, NO_MUTATION_STRING); + printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, gold, "gold", kindName, NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, NO_VAULT_STRING, NO_OPENS_VAULT_STRING, NO_CARRIED_BY_MONSTER_STRING, NO_ALLY_STATUS_STRING, NO_MUTATION_STRING); } else { if (piles == 1) { printf(" %i gold pieces\n", gold); @@ -216,7 +206,7 @@ static void printSeedCatalogFloorItems(boolean isCsvFormat) { static void printSeedCatalogAltars(boolean isCsvFormat) { short i, j; - boolean c_altars[50] = {0}; //IO.displayMachines uses 50 + boolean c_altars[50] = {0}; // IO.displayMachines uses 50 char vaultNumber[10] = ""; for (j = 0; j < DROWS; j++) { @@ -224,9 +214,8 @@ static void printSeedCatalogAltars(boolean isCsvFormat) { if (pmap[i][j].layers[0] == RESURRECTION_ALTAR) { sprintf(vaultNumber, "%i", pmap[i][j].machineNumber); if (isCsvFormat) { - printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, "altar", "resurrection altar", - NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, vaultNumber, NO_OPENS_VAULT_STRING, - NO_CARRIED_BY_MONSTER_STRING, NO_ALLY_STATUS_STRING, NO_MUTATION_STRING); + printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, "altar", "resurrection altar", NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, vaultNumber, NO_OPENS_VAULT_STRING, NO_CARRIED_BY_MONSTER_STRING, NO_ALLY_STATUS_STRING, + NO_MUTATION_STRING); } else { printf(" A resurrection altar (vault %s)\n", vaultNumber); } @@ -241,43 +230,41 @@ static void printSeedCatalogAltars(boolean isCsvFormat) { if (c_altars[i]) { sprintf(vaultNumber, "%i", i); if (isCsvFormat) { - printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, "altar", "commutation altar", - NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, vaultNumber, NO_OPENS_VAULT_STRING, - NO_CARRIED_BY_MONSTER_STRING, NO_ALLY_STATUS_STRING, NO_MUTATION_STRING); + printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, "altar", "commutation altar", NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, vaultNumber, NO_OPENS_VAULT_STRING, NO_CARRIED_BY_MONSTER_STRING, NO_ALLY_STATUS_STRING, + NO_MUTATION_STRING); } else { - printf(" A commutation altar (vault %s)\n",vaultNumber); + printf(" A commutation altar (vault %s)\n", vaultNumber); } } } } -void printSeedCatalog(uint64_t startingSeed, uint64_t numberOfSeedsToScan, unsigned int scanThroughDepth, - boolean isCsvFormat) { +void printSeedCatalog(uint64_t startingSeed, uint64_t numberOfSeedsToScan, unsigned int scanThroughDepth, boolean isCsvFormat) { uint64_t theSeed; char message[1000] = ""; rogue.nextGame = NG_NOTHING; initializeGameVariant(); - sprintf(message, "Brogue seed catalog, seeds %llu to %llu, through depth %u.\n" - "Generated with %s. Dungeons unchanged since %s.\n\n" - "To play one of these seeds, press control-N from the title screen" - " and enter the seed number.\n", - (unsigned long long) startingSeed, (unsigned long long) startingSeed + numberOfSeedsToScan - 1, scanThroughDepth, gameConst->versionString, - gameConst->dungeonVersionString); + sprintf(message, + "Brogue seed catalog, seeds %llu to %llu, through depth %u.\n" + "Generated with %s. Dungeons unchanged since %s.\n\n" + "To play one of these seeds, press control-N from the title screen" + " and enter the seed number.\n", + (unsigned long long)startingSeed, (unsigned long long)startingSeed + numberOfSeedsToScan - 1, scanThroughDepth, gameConst->versionString, gameConst->dungeonVersionString); if (isCsvFormat) { fprintf(stderr, "%s", message); - printf("%s\n",CSV_HEADER_STRING); + printf("%s\n", CSV_HEADER_STRING); } else { printf("%s", message); } for (theSeed = startingSeed; theSeed < startingSeed + numberOfSeedsToScan; theSeed++) { if (!isCsvFormat) { - printf("Seed %llu:\n", (unsigned long long) theSeed); + printf("Seed %llu:\n", (unsigned long long)theSeed); } - fprintf(stderr, "Scanning seed %llu...\n", (unsigned long long) theSeed); + fprintf(stderr, "Scanning seed %llu...\n", (unsigned long long)theSeed); rogue.nextGamePath[0] = '\0'; randomNumbersGenerated = 0; @@ -297,12 +284,11 @@ void printSeedCatalog(uint64_t startingSeed, uint64_t numberOfSeedsToScan, unsig printSeedCatalogFloorItems(isCsvFormat); printSeedCatalogMonsterItems(isCsvFormat); printSeedCatalogMonsters(isCsvFormat, false); // captives and allies only - if (rogue.depthLevel >= 13) { // resurrection & commutation altars can spawn starting on 13 + if (rogue.depthLevel >= 13) { // resurrection & commutation altars can spawn starting on 13 printSeedCatalogAltars(isCsvFormat); } } freeEverything(); } - } diff --git a/src/brogue/Time.c b/src/brogue/Time.c index 2ca43054..2dae6763 100644 --- a/src/brogue/Time.c +++ b/src/brogue/Time.c @@ -27,10 +27,7 @@ void exposeCreatureToFire(creature *monst) { char buf[COLS], buf2[COLS]; - if ((monst->bookkeepingFlags & MB_IS_DYING) - || monst->status[STATUS_IMMUNE_TO_FIRE] - || (monst->info.flags & MONST_INVULNERABLE) - || (monst->bookkeepingFlags & MB_SUBMERGED) + if ((monst->bookkeepingFlags & MB_IS_DYING) || monst->status[STATUS_IMMUNE_TO_FIRE] || (monst->info.flags & MONST_INVULNERABLE) || (monst->bookkeepingFlags & MB_SUBMERGED) || ((!monst->status[STATUS_LEVITATING]) && cellHasTMFlag(monst->loc.x, monst->loc.y, TM_EXTINGUISHES_FIRE))) { return; } @@ -39,7 +36,7 @@ void exposeCreatureToFire(creature *monst) { rogue.minersLight.lightColor = &fireForeColor; player.info.foreColor = &torchLightColor; refreshDungeonCell(player.loc.x, player.loc.y); - //updateVision(); // this screws up the firebolt visual effect by erasing it while a message is displayed + // updateVision(); // this screws up the firebolt visual effect by erasing it while a message is displayed combatMessage("you catch fire", &badMessageColor); } else if (canDirectlySeeMonster(monst)) { monsterName(buf, monst, true); @@ -53,10 +50,7 @@ void exposeCreatureToFire(creature *monst) { void updateFlavorText() { char buf[DCOLS * 3]; if (rogue.disturbed && !rogue.gameHasEnded) { - if (rogue.armor - && (rogue.armor->flags & ITEM_RUNIC) - && rogue.armor->enchant2 == A_RESPIRATION - && tileCatalog[pmapAt(player.loc)->layers[highestPriorityLayer(player.loc.x, player.loc.y, false)]].flags & T_RESPIRATION_IMMUNITIES) { + if (rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && rogue.armor->enchant2 == A_RESPIRATION && tileCatalog[pmapAt(player.loc)->layers[highestPriorityLayer(player.loc.x, player.loc.y, false)]].flags & T_RESPIRATION_IMMUNITIES) { flavorMessage("A pocket of cool, clean air swirls around you."); } else if (player.status[STATUS_LEVITATING]) { @@ -70,8 +64,7 @@ void updateFlavorText() { void updatePlayerUnderwaterness() { if (rogue.inWater) { - if (!cellHasTerrainFlag(player.loc.x, player.loc.y, T_IS_DEEP_WATER) || player.status[STATUS_LEVITATING] - || cellHasTerrainFlag(player.loc.x, player.loc.y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY))) { + if (!cellHasTerrainFlag(player.loc.x, player.loc.y, T_IS_DEEP_WATER) || player.status[STATUS_LEVITATING] || cellHasTerrainFlag(player.loc.x, player.loc.y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY))) { rogue.inWater = false; updateMinersLightRadius(); @@ -79,8 +72,7 @@ void updatePlayerUnderwaterness() { displayLevel(); } } else { - if (cellHasTerrainFlag(player.loc.x, player.loc.y, T_IS_DEEP_WATER) && !player.status[STATUS_LEVITATING] - && !cellHasTerrainFlag(player.loc.x, player.loc.y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY))) { + if (cellHasTerrainFlag(player.loc.x, player.loc.y, T_IS_DEEP_WATER) && !player.status[STATUS_LEVITATING] && !cellHasTerrainFlag(player.loc.x, player.loc.y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY))) { rogue.inWater = true; updateMinersLightRadius(); @@ -91,9 +83,7 @@ void updatePlayerUnderwaterness() { } boolean monsterShouldFall(creature *monst) { - return (!(monst->status[STATUS_LEVITATING]) - && cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_AUTO_DESCENT) - && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_ENTANGLES | T_OBSTRUCTS_PASSABILITY) + return (!(monst->status[STATUS_LEVITATING]) && cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_AUTO_DESCENT) && !cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_ENTANGLES | T_OBSTRUCTS_PASSABILITY) && !(monst->bookkeepingFlags & MB_PREPLACED)); } @@ -113,18 +103,12 @@ void applyInstantTileEffectsToCreature(creature *monst) { if (!player.status[STATUS_LEVITATING]) { pmap[*x][*y].flags |= KNOWN_TO_BE_TRAP_FREE; } - } else if (!player.status[STATUS_HALLUCINATING] - && !monst->status[STATUS_LEVITATING] - && canSeeMonster(monst) - && !(cellHasTerrainFlag(*x, *y, T_IS_DF_TRAP))) { + } else if (!player.status[STATUS_HALLUCINATING] && !monst->status[STATUS_LEVITATING] && canSeeMonster(monst) && !(cellHasTerrainFlag(*x, *y, T_IS_DF_TRAP))) { pmap[*x][*y].flags |= KNOWN_TO_BE_TRAP_FREE; } // You will discover the secrets of any tile you stand on. - if (monst == &player - && !(monst->status[STATUS_LEVITATING]) - && cellHasTMFlag(*x, *y, TM_IS_SECRET) - && playerCanSee(*x, *y)) { + if (monst == &player && !(monst->status[STATUS_LEVITATING]) && cellHasTMFlag(*x, *y, TM_IS_SECRET) && playerCanSee(*x, *y)) { discover(*x, *y); } @@ -140,9 +124,7 @@ void applyInstantTileEffectsToCreature(creature *monst) { } // Obstructed krakens can't seize their prey. - if ((monst->bookkeepingFlags & MB_SEIZING) - && (cellHasTerrainFlag(*x, *y, T_OBSTRUCTS_PASSABILITY)) - && !(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { + if ((monst->bookkeepingFlags & MB_SEIZING) && (cellHasTerrainFlag(*x, *y, T_OBSTRUCTS_PASSABILITY)) && !(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS)) { monst->bookkeepingFlags &= ~MB_SEIZING; } @@ -155,25 +137,19 @@ void applyInstantTileEffectsToCreature(creature *monst) { monst->bookkeepingFlags |= MB_IS_FALLING; } return; - } else { // it's a monster + } else { // it's a monster monst->bookkeepingFlags |= MB_IS_FALLING; // handled at end of turn } } // lava - if (!(monst->status[STATUS_LEVITATING]) - && !(monst->status[STATUS_IMMUNE_TO_FIRE]) - && !(monst->info.flags & MONST_INVULNERABLE) - && !cellHasTerrainFlag(*x, *y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY)) - && !cellHasTMFlag(*x, *y, TM_EXTINGUISHES_FIRE) - && cellHasTerrainFlag(*x, *y, T_LAVA_INSTA_DEATH)) { + if (!(monst->status[STATUS_LEVITATING]) && !(monst->status[STATUS_IMMUNE_TO_FIRE]) && !(monst->info.flags & MONST_INVULNERABLE) && !cellHasTerrainFlag(*x, *y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY)) + && !cellHasTMFlag(*x, *y, TM_EXTINGUISHES_FIRE) && cellHasTerrainFlag(*x, *y, T_LAVA_INSTA_DEATH)) { if (monst == &player) { - sprintf(buf, "you plunge into %s!", - tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_LAVA_INSTA_DEATH)]].description); + sprintf(buf, "you plunge into %s!", tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_LAVA_INSTA_DEATH)]].description); message(buf, REQUIRE_ACKNOWLEDGMENT); - sprintf(buf, "Killed by %s", - tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_LAVA_INSTA_DEATH)]].description); + sprintf(buf, "Killed by %s", tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_LAVA_INSTA_DEATH)]].description); gameOver(buf, true); return; } else { // it's a monster @@ -197,26 +173,17 @@ void applyInstantTileEffectsToCreature(creature *monst) { } // Water puts out fire. - if (cellHasTMFlag(*x, *y, TM_EXTINGUISHES_FIRE) - && monst->status[STATUS_BURNING] - && !monst->status[STATUS_LEVITATING] - && !(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) - && !(monst->info.flags & MONST_FIERY)) { + if (cellHasTMFlag(*x, *y, TM_EXTINGUISHES_FIRE) && monst->status[STATUS_BURNING] && !monst->status[STATUS_LEVITATING] && !(monst->info.flags & MONST_ATTACKABLE_THRU_WALLS) && !(monst->info.flags & MONST_FIERY)) { extinguishFireOnCreature(monst); } // If you see a monster use a secret door, you discover it. - if (playerCanSee(*x, *y) - && cellHasTMFlag(*x, *y, TM_IS_SECRET) - && (cellHasTerrainFlag(*x, *y, T_OBSTRUCTS_PASSABILITY))) { + if (playerCanSee(*x, *y) && cellHasTMFlag(*x, *y, TM_IS_SECRET) && (cellHasTerrainFlag(*x, *y, T_OBSTRUCTS_PASSABILITY))) { discover(*x, *y); } // Pressure plates. - if (!(monst->status[STATUS_LEVITATING]) - && !(monst->bookkeepingFlags & MB_SUBMERGED) - && (!cellHasTMFlag(*x, *y, TM_ALLOWS_SUBMERGING) || !(monst->info.flags & MONST_SUBMERGES)) - && cellHasTerrainFlag(*x, *y, T_IS_DF_TRAP) + if (!(monst->status[STATUS_LEVITATING]) && !(monst->bookkeepingFlags & MB_SUBMERGED) && (!cellHasTMFlag(*x, *y, TM_ALLOWS_SUBMERGING) || !(monst->info.flags & MONST_SUBMERGES)) && cellHasTerrainFlag(*x, *y, T_IS_DF_TRAP) && !(pmap[*x][*y].flags & PRESSURE_PLATE_DEPRESSED)) { pmap[*x][*y].flags |= PRESSURE_PLATE_DEPRESSED; @@ -263,9 +230,7 @@ void applyInstantTileEffectsToCreature(creature *monst) { } } - if (cellHasTMFlag(*x, *y, TM_PROMOTES_ON_SACRIFICE_ENTRY) - && monst->machineHome == pmap[*x][*y].machineNumber - && (monst->bookkeepingFlags & MB_MARKED_FOR_SACRIFICE)) { + if (cellHasTMFlag(*x, *y, TM_PROMOTES_ON_SACRIFICE_ENTRY) && monst->machineHome == pmap[*x][*y].machineNumber && (monst->bookkeepingFlags & MB_MARKED_FOR_SACRIFICE)) { // Subject to same caveats as T_PROMOTES_ON_STEP above. for (layer = 0; layer < NUMBER_TERRAIN_LAYERS; layer++) { if (tileCatalog[pmap[*x][*y].layers[layer]].mechFlags & TM_PROMOTES_ON_SACRIFICE_ENTRY) { @@ -275,37 +240,33 @@ void applyInstantTileEffectsToCreature(creature *monst) { } // spiderwebs - if (cellHasTerrainFlag(*x, *y, T_ENTANGLES) && !monst->status[STATUS_STUCK] - && !(monst->info.flags & (MONST_IMMUNE_TO_WEBS | MONST_INVULNERABLE)) - && !(monst->bookkeepingFlags & MB_SUBMERGED)) { + if (cellHasTerrainFlag(*x, *y, T_ENTANGLES) && !monst->status[STATUS_STUCK] && !(monst->info.flags & (MONST_IMMUNE_TO_WEBS | MONST_INVULNERABLE)) && !(monst->bookkeepingFlags & MB_SUBMERGED)) { monst->status[STATUS_STUCK] = monst->maxStatus[STATUS_STUCK] = rand_range(3, 7); if (monst == &player) { if (!rogue.automationActive) { // Don't interrupt exploration with this message. - sprintf(buf2, "you are stuck fast in %s!", - tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_ENTANGLES)]].description); + sprintf(buf2, "you are stuck fast in %s!", tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_ENTANGLES)]].description); message(buf2, 0); } } else if (canDirectlySeeMonster(monst)) { // it's a monster if (!rogue.automationActive) { monsterName(buf, monst, true); - sprintf(buf2, "%s is stuck fast in %s!", buf, - tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_ENTANGLES)]].description); + sprintf(buf2, "%s is stuck fast in %s!", buf, tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_ENTANGLES)]].description); message(buf2, 0); } } } // explosions - if (cellHasTerrainFlag(*x, *y, T_CAUSES_EXPLOSIVE_DAMAGE) && !monst->status[STATUS_EXPLOSION_IMMUNITY] - && !(monst->bookkeepingFlags & MB_SUBMERGED)) { + if (cellHasTerrainFlag(*x, *y, T_CAUSES_EXPLOSIVE_DAMAGE) && !monst->status[STATUS_EXPLOSION_IMMUNITY] && !(monst->bookkeepingFlags & MB_SUBMERGED)) { damage = rand_range(15, 20); damage = max(damage, monst->info.maxHP / 2); monst->status[STATUS_EXPLOSION_IMMUNITY] = 5; if (monst == &player) { rogue.disturbed = true; - for (layer = 0; layer < NUMBER_TERRAIN_LAYERS && !(tileCatalog[pmap[*x][*y].layers[layer]].flags & T_CAUSES_EXPLOSIVE_DAMAGE); layer++); + for (layer = 0; layer < NUMBER_TERRAIN_LAYERS && !(tileCatalog[pmap[*x][*y].layers[layer]].flags & T_CAUSES_EXPLOSIVE_DAMAGE); layer++) + ; message(tileCatalog[pmap[*x][*y].layers[layer]].flavorText, 0); if (rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && rogue.armor->enchant2 == A_DAMPENING) { itemName(rogue.armor, buf2, false, false, NULL); @@ -329,17 +290,14 @@ void applyInstantTileEffectsToCreature(creature *monst) { strcpy(buf3, tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_CAUSES_EXPLOSIVE_DAMAGE)]].description); if (inflictDamage(NULL, monst, damage, &yellow, false)) { // if killed - sprintf(buf2, "%s %s %s.", buf, - (monst->info.flags & MONST_INANIMATE) ? "is destroyed by" : "dies in", - buf3); + sprintf(buf2, "%s %s %s.", buf, (monst->info.flags & MONST_INANIMATE) ? "is destroyed by" : "dies in", buf3); messageWithColor(buf2, messageColorFromVictim(monst), 0); killCreature(monst, false); refreshDungeonCell(*x, *y); return; } else { // if survived - sprintf(buf2, "%s engulfs %s.", - tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_CAUSES_EXPLOSIVE_DAMAGE)]].description, buf); + sprintf(buf2, "%s engulfs %s.", tileCatalog[pmap[*x][*y].layers[layerWithFlag(*x, *y, T_CAUSES_EXPLOSIVE_DAMAGE)]].description, buf); messageWithColor(buf2, messageColorFromVictim(monst), 0); } } @@ -347,11 +305,7 @@ void applyInstantTileEffectsToCreature(creature *monst) { // Toxic gases! // If it's the player, and he's wearing armor of respiration, then no effect from toxic gases. - if (monst == &player - && cellHasTerrainFlag(*x, *y, T_RESPIRATION_IMMUNITIES) - && rogue.armor - && (rogue.armor->flags & ITEM_RUNIC) - && rogue.armor->enchant2 == A_RESPIRATION) { + if (monst == &player && cellHasTerrainFlag(*x, *y, T_RESPIRATION_IMMUNITIES) && rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && rogue.armor->enchant2 == A_RESPIRATION) { if (!(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED)) { message("Your armor trembles and a pocket of clean air swirls around you.", 0); autoIdentify(rogue.armor); @@ -359,9 +313,7 @@ void applyInstantTileEffectsToCreature(creature *monst) { } else { // zombie gas - if (cellHasTerrainFlag(*x, *y, T_CAUSES_NAUSEA) - && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) - && !(monst->bookkeepingFlags & MB_SUBMERGED)) { + if (cellHasTerrainFlag(*x, *y, T_CAUSES_NAUSEA) && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) && !(monst->bookkeepingFlags & MB_SUBMERGED)) { if (monst == &player) { rogue.disturbed = true; } @@ -371,8 +323,7 @@ void applyInstantTileEffectsToCreature(creature *monst) { } flashMonster(monst, &brown, 100); monsterName(buf, monst, true); - sprintf(buf2, "%s choke%s and gag%s on the overpowering stench of decay.", buf, - (monst == &player ? "": "s"), (monst == &player ? "": "s")); + sprintf(buf2, "%s choke%s and gag%s on the overpowering stench of decay.", buf, (monst == &player ? "" : "s"), (monst == &player ? "" : "s")); message(buf2, 0); } monst->status[STATUS_NAUSEOUS] = monst->maxStatus[STATUS_NAUSEOUS] = max(monst->status[STATUS_NAUSEOUS], 20); @@ -389,21 +340,19 @@ void applyInstantTileEffectsToCreature(creature *monst) { } flashMonster(monst, &confusionGasColor, 100); monsterName(buf, monst, true); - sprintf(buf2, "%s %s very confused!", buf, (monst == &player ? "feel": "looks")); + sprintf(buf2, "%s %s very confused!", buf, (monst == &player ? "feel" : "looks")); message(buf2, 0); } monst->status[STATUS_CONFUSED] = monst->maxStatus[STATUS_CONFUSED] = max(monst->status[STATUS_CONFUSED], 25); } // paralysis gas - if (cellHasTerrainFlag(*x, *y, T_CAUSES_PARALYSIS) - && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) - && !(monst->bookkeepingFlags & MB_SUBMERGED)) { + if (cellHasTerrainFlag(*x, *y, T_CAUSES_PARALYSIS) && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) && !(monst->bookkeepingFlags & MB_SUBMERGED)) { if (canDirectlySeeMonster(monst) && !monst->status[STATUS_PARALYZED]) { flashMonster(monst, &pink, 100); monsterName(buf, monst, true); - sprintf(buf2, "%s %s paralyzed!", buf, (monst == &player ? "are": "is")); + sprintf(buf2, "%s %s paralyzed!", buf, (monst == &player ? "are" : "is")); message(buf2, (monst == &player) ? REQUIRE_ACKNOWLEDGMENT : 0); } monst->status[STATUS_PARALYZED] = monst->maxStatus[STATUS_PARALYZED] = max(monst->status[STATUS_PARALYZED], 20); @@ -414,9 +363,7 @@ void applyInstantTileEffectsToCreature(creature *monst) { } // poisonous lichen - if (cellHasTerrainFlag(*x, *y, T_CAUSES_POISON) - && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) - && !monst->status[STATUS_LEVITATING]) { + if (cellHasTerrainFlag(*x, *y, T_CAUSES_POISON) && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) && !monst->status[STATUS_LEVITATING]) { if (monst == &player && !player.status[STATUS_POISONED]) { rogue.disturbed = true; @@ -438,13 +385,10 @@ void applyInstantTileEffectsToCreature(creature *monst) { if (cellHasTerrainFlag(*x, *y, T_IS_FIRE)) { exposeCreatureToFire(monst); } else if (cellHasTerrainFlag(*x, *y, T_IS_FLAMMABLE) - // We should only expose to fire if it is flammable and not on fire. However, when - // gas burns, it only sets the volume to 0 and doesn't clear the layer (for visual - // reasons). This can cause crashes if the fire tile fails to spawn, so we also exclude it. - && !(pmap[*x][*y].layers[GAS] != NOTHING && pmap[*x][*y].volume == 0) - && !cellHasTerrainFlag(*x, *y, T_IS_FIRE) - && monst->status[STATUS_BURNING] - && !(monst->bookkeepingFlags & (MB_SUBMERGED | MB_IS_FALLING))) { + // We should only expose to fire if it is flammable and not on fire. However, when + // gas burns, it only sets the volume to 0 and doesn't clear the layer (for visual + // reasons). This can cause crashes if the fire tile fails to spawn, so we also exclude it. + && !(pmap[*x][*y].layers[GAS] != NOTHING && pmap[*x][*y].volume == 0) && !cellHasTerrainFlag(*x, *y, T_IS_FIRE) && monst->status[STATUS_BURNING] && !(monst->bookkeepingFlags & (MB_SUBMERGED | MB_IS_FALLING))) { exposeTileToFire(*x, *y, true); } @@ -461,10 +405,7 @@ void applyGradualTileEffectsToCreature(creature *monst, short ticks) { item *theItem; enum dungeonLayers layer; - if (!(monst->status[STATUS_LEVITATING]) - && cellHasTerrainFlag(x, y, T_IS_DEEP_WATER) - && !cellHasTerrainFlag(x, y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY)) - && !(monst->info.flags & MONST_IMMUNE_TO_WATER)) { + if (!(monst->status[STATUS_LEVITATING]) && cellHasTerrainFlag(x, y, T_IS_DEEP_WATER) && !cellHasTerrainFlag(x, y, (T_ENTANGLES | T_OBSTRUCTS_PASSABILITY)) && !(monst->info.flags & MONST_IMMUNE_TO_WATER)) { if (monst == &player) { if (!(pmap[x][y].flags & HAS_ITEM) && rand_percent(ticks * 50 / 100)) { itemCandidates = numberOfMatchingPackItems(ALL_ITEMS, 0, (ITEM_EQUIPPED), false); @@ -482,9 +423,7 @@ void applyGradualTileEffectsToCreature(creature *monst, short ticks) { theItem = dropItem(theItem); if (theItem) { itemName(theItem, buf2, false, true, NULL); - sprintf(buf, "%s float%s away in the current!", - buf2, - (theItem->quantity == 1 ? "s" : "")); + sprintf(buf, "%s float%s away in the current!", buf2, (theItem->quantity == 1 ? "s" : "")); messageWithColor(buf, &itemMessageColor, 0); } } @@ -494,13 +433,12 @@ void applyGradualTileEffectsToCreature(creature *monst, short ticks) { } } - if (cellHasTerrainFlag(x, y, T_CAUSES_DAMAGE) - && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) - && !(monst->bookkeepingFlags & MB_SUBMERGED)) { + if (cellHasTerrainFlag(x, y, T_CAUSES_DAMAGE) && !(monst->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) && !(monst->bookkeepingFlags & MB_SUBMERGED)) { damage = (monst->info.maxHP / 15) * ticks / 100; damage = max(1, damage); - for (layer = 0; layer < NUMBER_TERRAIN_LAYERS && !(tileCatalog[pmap[x][y].layers[layer]].flags & T_CAUSES_DAMAGE); layer++); + for (layer = 0; layer < NUMBER_TERRAIN_LAYERS && !(tileCatalog[pmap[x][y].layers[layer]].flags & T_CAUSES_DAMAGE); layer++) + ; if (monst == &player) { if (rogue.armor && (rogue.armor->flags & ITEM_RUNIC) && rogue.armor->enchant2 == A_RESPIRATION) { if (!(rogue.armor->flags & ITEM_RUNIC_IDENTIFIED)) { @@ -534,9 +472,7 @@ void applyGradualTileEffectsToCreature(creature *monst, short ticks) { } } - if (cellHasTerrainFlag(x, y, T_CAUSES_HEALING) - && !(monst->info.flags & MONST_INANIMATE) - && !(monst->bookkeepingFlags & MB_SUBMERGED)) { + if (cellHasTerrainFlag(x, y, T_CAUSES_HEALING) && !(monst->info.flags & MONST_INANIMATE) && !(monst->bookkeepingFlags & MB_SUBMERGED)) { damage = (monst->info.maxHP / 15) * ticks / 100; damage = max(1, damage); @@ -554,8 +490,8 @@ void updateClairvoyance() { boolean cursed; unsigned long cFlags; - for (i=0; icategory & ARMOR)) { + if (!theArmor || !(theArmor->category & ARMOR)) { return 0; } @@ -718,8 +652,8 @@ short currentStealthRange() { void demoteVisibility() { short i, j; - for (i=0; iquantity == 1 ? "s" : ""); + sprintf(buf2, "%s burn%s up!", buf1, theItem->quantity == 1 ? "s" : ""); x = theItem->loc.x; y = theItem->loc.y; removeItemFromChain(theItem, floorItems); @@ -879,13 +811,10 @@ void flashCreatureAlert(creature *monst, char msg[200], const color *foreColor, } void handleHealthAlerts() { - short i, currentPercent, previousPercent, - thresholds[] = {5, 10, 25, 40}, - pThresholds[] = {100, 90, 50}; + short i, currentPercent, previousPercent, thresholds[] = {5, 10, 25, 40}, pThresholds[] = {100, 90, 50}; char buf[DCOLS]; - const short healthThresholdsCount = 4, - poisonThresholdsCount = 3; + const short healthThresholdsCount = 4, poisonThresholdsCount = 3; assureCosmeticRNG; @@ -893,7 +822,7 @@ void handleHealthAlerts() { previousPercent = player.previousHealthPoints * 100 / player.info.maxHP; if (currentPercent < previousPercent && !rogue.gameHasEnded) { - for (i=0; i < healthThresholdsCount; i++) { + for (i = 0; i < healthThresholdsCount; i++) { if (currentPercent < thresholds[i] && previousPercent >= thresholds[i]) { sprintf(buf, " <%i%% health ", thresholds[i]); flashCreatureAlert(&player, buf, &badMessageColor, &darkRed); @@ -906,7 +835,7 @@ void handleHealthAlerts() { currentPercent = player.status[STATUS_POISONED] * player.poisonAmount * 100 / player.currentHP; if (currentPercent > rogue.previousPoisonPercent && !rogue.gameHasEnded) { - for (i=0; i < poisonThresholdsCount; i++) { + for (i = 0; i < poisonThresholdsCount; i++) { if (currentPercent > pThresholds[i] && rogue.previousPoisonPercent <= pThresholds[i]) { if (currentPercent < 100) { sprintf(buf, " >%i%% poisoned ", pThresholds[i]); @@ -926,16 +855,12 @@ void handleHealthAlerts() { void addXPXPToAlly(short XPXP, creature *monst) { char theMonsterName[100], buf[200]; - if (!(monst->info.flags & (MONST_INANIMATE | MONST_IMMOBILE)) - && !(monst->bookkeepingFlags & MB_TELEPATHICALLY_REVEALED) - && monst->creatureState == MONSTER_ALLY - && monst->spawnDepth <= rogue.depthLevel + if (!(monst->info.flags & (MONST_INANIMATE | MONST_IMMOBILE)) && !(monst->bookkeepingFlags & MB_TELEPATHICALLY_REVEALED) && monst->creatureState == MONSTER_ALLY && monst->spawnDepth <= rogue.depthLevel && rogue.depthLevel <= gameConst->amuletLevel) { monst->xpxp += XPXP; - //printf("\n%i xpxp added to your %s this turn.", rogue.xpxpThisTurn, monst->info.monsterName); - if (monst->xpxp >= XPXP_NEEDED_FOR_TELEPATHIC_BOND - && !(monst->bookkeepingFlags & MB_TELEPATHICALLY_REVEALED)) { + // printf("\n%i xpxp added to your %s this turn.", rogue.xpxpThisTurn, monst->info.monsterName); + if (monst->xpxp >= XPXP_NEEDED_FOR_TELEPATHIC_BOND && !(monst->bookkeepingFlags & MB_TELEPATHICALLY_REVEALED)) { monst->bookkeepingFlags |= MB_TELEPATHICALLY_REVEALED; updateVision(true); @@ -950,7 +875,7 @@ void addXPXPToAlly(short XPXP, creature *monst) { } void handleXPXP() { - //char buf[DCOLS*2], theMonsterName[50]; + // char buf[DCOLS*2], theMonsterName[50]; for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); @@ -975,13 +900,12 @@ void playerFalls() { short damage; short layer; - if (cellHasTMFlag(player.loc.x, player.loc.y, TM_IS_SECRET) - && playerCanSee(player.loc.x, player.loc.y)) { + if (cellHasTMFlag(player.loc.x, player.loc.y, TM_IS_SECRET) && playerCanSee(player.loc.x, player.loc.y)) { discover(player.loc.x, player.loc.y); } - monstersFall(); // Monsters must fall with the player rather than getting suspended on the previous level. + monstersFall(); // Monsters must fall with the player rather than getting suspended on the previous level. updateFloorItems(); // Likewise, items should fall with the player rather than getting suspended above. layer = layerWithFlag(player.loc.x, player.loc.y, T_AUTO_DESCENT); @@ -1024,8 +948,6 @@ void playerFalls() { rogue.flareCount = 0; } - - void activateMachine(short machineNumber) { short i, j, x, y, layer, sRows[DROWS], sCols[DCOLS], monsterCount, maxMonsters; @@ -1034,14 +956,11 @@ void activateMachine(short machineNumber) { fillSequentialList(sRows, DROWS); shuffleList(sRows, DROWS); - for (i=0; imachineHome == machineNumber - && monst->spawnDepth == rogue.depthLevel - && (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION)) { + if (monst->machineHome == machineNumber && monst->spawnDepth == rogue.depthLevel && (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION)) { monsterCount++; @@ -1070,7 +987,7 @@ void activateMachine(short machineNumber) { activatedMonsterList[monsterCount - 1] = monst; } } - for (i=0; ibookkeepingFlags & MB_IS_DYING)) { monstersTurn(activatedMonsterList[i]); } @@ -1083,10 +1000,9 @@ void activateMachine(short machineNumber) { boolean circuitBreakersPreventActivation(short machineNumber) { short i, j; - for (i=0; imechFlags & TM_IS_WIRED) - && !(pmap[x][y].flags & IS_POWERED) - && !circuitBreakersPreventActivation(pmap[x][y].machineNumber)) { + if (!useFireDF && (tile->mechFlags & TM_IS_WIRED) && !(pmap[x][y].flags & IS_POWERED) && !circuitBreakersPreventActivation(pmap[x][y].machineNumber)) { // Send power through all cells in the same machine that are not IS_POWERED, // and on any such cell, promote each terrain layer that is T_IS_WIRED. // Note that machines need not be contiguous. @@ -1128,8 +1042,8 @@ void promoteTile(short x, short y, enum dungeonLayers layer, boolean useFireDF) activateMachine(pmap[x][y].machineNumber); // It lives!!! // Power fades from the map immediately after we finish. - for (i=0; i ignitionChance) { ignitionChance = tileCatalog[pmap[x][y].layers[layer]].chanceToIgnite; } @@ -1190,8 +1103,7 @@ boolean exposeTileToFire(short x, short y, boolean alwaysIgnite) { for (dir = 0, explosiveNeighborCount = 0; dir < DIRECTION_COUNT; dir++) { newX = x + nbDirs[dir][0]; newY = y + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && (cellHasTerrainFlag(newX, newY, T_IS_FIRE | T_OBSTRUCTS_GAS) || cellHasTMFlag(newX, newY, TM_EXPLOSIVE_PROMOTE))) { + if (coordinatesAreInMap(newX, newY) && (cellHasTerrainFlag(newX, newY, T_IS_FIRE | T_OBSTRUCTS_GAS) || cellHasTMFlag(newX, newY, TM_EXPLOSIVE_PROMOTE))) { explosiveNeighborCount++; } @@ -1202,7 +1114,7 @@ boolean exposeTileToFire(short x, short y, boolean alwaysIgnite) { } // Flammable layers are consumed. - for (layer=0; layer < NUMBER_TERRAIN_LAYERS; layer++) { + for (layer = 0; layer < NUMBER_TERRAIN_LAYERS; layer++) { if (tileCatalog[pmap[x][y].layers[layer]].flags & T_IS_FLAMMABLE) { // pmap[x][y].layers[GAS] is not cleared here, which is a bug. // We preserve the layer anyways because this results in nicer gas burning behavior. @@ -1226,24 +1138,23 @@ void updateVolumetricMedia() { enum directions dir; unsigned short newGasVolume[DCOLS][DROWS]; - for (i=0; i 3) { @@ -1282,8 +1193,7 @@ void updateVolumetricMedia() { for (dir = 0; dir < DIRECTION_COUNT; dir++) { newX = i + nbDirs[dir][0]; newY = j + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_GAS)) { + if (coordinatesAreInMap(newX, newY) && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_GAS)) { numSpaces++; } @@ -1292,8 +1202,7 @@ void updateVolumetricMedia() { for (dir = 0; dir < DIRECTION_COUNT; dir++) { newX = i + nbDirs[dir][0]; newY = j + nbDirs[dir][1]; - if (coordinatesAreInMap(newX, newY) - && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_GAS)) { + if (coordinatesAreInMap(newX, newY) && !cellHasTerrainFlag(newX, newY, T_OBSTRUCTS_GAS)) { newGasVolume[newX][newY] += (pmap[i][j].volume / numSpaces); if (pmap[i][j].volume / numSpaces) { @@ -1308,8 +1217,8 @@ void updateVolumetricMedia() { } } - for (i=0; idepth = rogue.depthLevel + 1; @@ -1416,15 +1325,15 @@ void updateEnvironment() { monstersFall(); // reset exposedToFire - for (i=0; ipromoteChance < 0) { promoteChance = 0; for (direction = 0; direction < 4; direction++) { - if (coordinatesAreInMap(i + nbDirs[direction][0], j + nbDirs[direction][1]) - && !cellHasTerrainFlag(i + nbDirs[direction][0], j + nbDirs[direction][1], T_OBSTRUCTS_PASSABILITY) - && pmap[i + nbDirs[direction][0]][j + nbDirs[direction][1]].layers[layer] != pmap[i][j].layers[layer] - && !(pmap[i][j].flags & CAUGHT_FIRE_THIS_TURN)) { + if (coordinatesAreInMap(i + nbDirs[direction][0], j + nbDirs[direction][1]) && !cellHasTerrainFlag(i + nbDirs[direction][0], j + nbDirs[direction][1], T_OBSTRUCTS_PASSABILITY) + && pmap[i + nbDirs[direction][0]][j + nbDirs[direction][1]].layers[layer] != pmap[i][j].layers[layer] && !(pmap[i][j].flags & CAUGHT_FIRE_THIS_TURN)) { promoteChance += -1 * tile->promoteChance; } } } else { promoteChance = tile->promoteChance; } - if (promoteChance - && !(pmap[i][j].flags & CAUGHT_FIRE_THIS_TURN) - && rand_range(0, 10000) < promoteChance) { + if (promoteChance && !(pmap[i][j].flags & CAUGHT_FIRE_THIS_TURN) && rand_range(0, 10000) < promoteChance) { promotions[i][j] |= Fl(layer); - //promoteTile(i, j, layer, false); + // promoteTile(i, j, layer, false); } } } } // Second pass, do the promotions: - for (i=0; i grid[newX][newY] + 1) { + if (coordinatesAreInMap(newX, newY) && grid[x][y] > grid[newX][newY] + 1) { grid[x][y] = grid[newX][newY] + 1; } @@ -1602,14 +1504,13 @@ void updateSafetyMap() { playerCostMap = allocGrid(); monsterCostMap = allocGrid(); - for (i=0; icreatureState == MONSTER_SLEEPING - || monst->turnsSpentStationary > 2 - || (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) - || monst->creatureState == MONSTER_ALLY) + monst = monsterAtLoc((pos){i, j}); + if ((monst->creatureState == MONSTER_SLEEPING || monst->turnsSpentStationary > 2 || (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) || monst->creatureState == MONSTER_ALLY) && monst->creatureState != MONSTER_FLEEING) { playerCostMap[i][j] = 1; @@ -1658,9 +1556,7 @@ void updateSafetyMap() { playerCostMap[i][j] = 5; } monsterCostMap[i][j] = 5; - } else if (cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) - && cellHasTMFlag(i, j, TM_IS_SECRET) && !(discoveredTerrainFlagsAtLoc(i, j) & T_OBSTRUCTS_PASSABILITY) - && !(pmap[i][j].flags & IN_FIELD_OF_VIEW)) { + } else if (cellHasTerrainFlag(i, j, T_OBSTRUCTS_PASSABILITY) && cellHasTMFlag(i, j, TM_IS_SECRET) && !(discoveredTerrainFlagsAtLoc(i, j) & T_OBSTRUCTS_PASSABILITY) && !(pmap[i][j].flags & IN_FIELD_OF_VIEW)) { // Secret door that the player can't currently see playerCostMap[i][j] = 100; monsterCostMap[i][j] = 1; @@ -1682,11 +1578,9 @@ void updateSafetyMap() { dijkstraScan(safetyMap, playerCostMap, false); - for (i=0; iturnsSpentStationary > 1 || (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION))) - || (cellHasTerrainFlag(i, j, T_PATHING_BLOCKER & ~T_HARMFUL_TERRAIN) && !cellHasTMFlag(i, j, TM_IS_SECRET))) { + } else if ((monst && (monst->turnsSpentStationary > 1 || (monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION))) || (cellHasTerrainFlag(i, j, T_PATHING_BLOCKER & ~T_HARMFUL_TERRAIN) && !cellHasTMFlag(i, j, TM_IS_SECRET))) { costMap[i][j] = PDS_FORBIDDEN; rogue.mapToSafeTerrain[i][j] = 30000; @@ -1768,14 +1660,12 @@ void updateSafeTerrainMap() { void processIncrementalAutoID() { item *theItem, *autoIdentifyItems[3] = {rogue.armor, rogue.ringLeft, rogue.ringRight}; - char buf[DCOLS*3], theItemName[DCOLS*3]; + char buf[DCOLS * 3], theItemName[DCOLS * 3]; short i; - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) { theItem = autoIdentifyItems[i]; - if (theItem - && theItem->charges > 0 - && (!(theItem->flags & ITEM_IDENTIFIED) || ((theItem->category & RING) && !ringTable[theItem->kind].identified))) { + if (theItem && theItem->charges > 0 && (!(theItem->flags & ITEM_IDENTIFIED) || ((theItem->category & RING) && !ringTable[theItem->kind].identified))) { theItem->charges--; if (theItem->charges <= 0) { @@ -1807,7 +1697,7 @@ short staffChargeDuration(const item *theItem) { // Multiplier can be negative, in which case staffs and charms will be drained instead of recharged. void rechargeItemsIncrementally(short multiplier) { item *theItem; - char buf[DCOLS*3], theItemName[DCOLS*3]; + char buf[DCOLS * 3], theItemName[DCOLS * 3]; short rechargeIncrement, staffRechargeDuration; if (rogue.wisdomBonus) { @@ -1821,8 +1711,7 @@ void rechargeItemsIncrementally(short multiplier) { for (theItem = packItems->nextItem; theItem != NULL; theItem = theItem->nextItem) { if (theItem->category & STAFF) { - if (theItem->charges < theItem->enchant1 && rechargeIncrement > 0 - || theItem->charges > 0 && rechargeIncrement < 0) { + if (theItem->charges < theItem->enchant1 && rechargeIncrement > 0 || theItem->charges > 0 && rechargeIncrement < 0) { theItem->enchant2 -= rechargeIncrement; } @@ -1886,23 +1775,19 @@ void monsterEntersLevel(creature *monst, short n) { monst->targetCorpseLoc = INVALID_POS; if (!pit) { - getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), monst->loc.x, monst->loc.y, true, - T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)), 0, - avoidedFlagsForMonster(&(monst->info)), HAS_STAIRS, false); + getQualifyingPathLocNear(&(monst->loc.x), &(monst->loc.y), monst->loc.x, monst->loc.y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)), 0, avoidedFlagsForMonster(&(monst->info)), HAS_STAIRS, false); } - if (!pit - && (pmapAt(monst->loc)->flags & (HAS_PLAYER | HAS_MONSTER)) - && !(terrainFlags(monst->loc.x, monst->loc.y) & avoidedFlagsForMonster(&(monst->info)))) { + if (!pit && (pmapAt(monst->loc)->flags & (HAS_PLAYER | HAS_MONSTER)) && !(terrainFlags(monst->loc.x, monst->loc.y) & avoidedFlagsForMonster(&(monst->info)))) { // Monsters using the stairs will displace any creatures already located there, to thwart stair-dancing. creature *prevMonst = monsterAtLoc(monst->loc); brogueAssert(prevMonst); - getQualifyingPathLocNear(&(prevMonst->loc.x), &(prevMonst->loc.y), monst->loc.x, monst->loc.y, true, - T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(prevMonst->info)), 0, - avoidedFlagsForMonster(&(prevMonst->info)), (HAS_MONSTER | HAS_PLAYER | HAS_STAIRS), false); + getQualifyingPathLocNear(&(prevMonst->loc.x), &(prevMonst->loc.y), monst->loc.x, monst->loc.y, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(prevMonst->info)), 0, avoidedFlagsForMonster(&(prevMonst->info)), + (HAS_MONSTER | HAS_PLAYER | HAS_STAIRS), false); pmapAt(monst->loc)->flags &= ~(HAS_PLAYER | HAS_MONSTER); pmapAt(prevMonst->loc)->flags |= (prevMonst == &player ? HAS_PLAYER : HAS_MONSTER); refreshDungeonCell(prevMonst->loc.x, prevMonst->loc.y); - //DEBUG printf("\nBumped a creature (%s) from (%i, %i) to (%i, %i).", prevMonst->info.monsterName, monst->loc.x, monst->loc.y, prevMonst->loc.x, prevMonst->loc.y); + // DEBUG printf("\nBumped a creature (%s) from (%i, %i) to (%i, %i).", prevMonst->info.monsterName, + // monst->loc.x, monst->loc.y, prevMonst->loc.x, prevMonst->loc.y); } // remove traversing monster from other level monster chain @@ -1914,7 +1799,7 @@ void monsterEntersLevel(creature *monst, short n) { monst->bookkeepingFlags |= MB_PREPLACED; monst->bookkeepingFlags &= ~MB_IS_FALLING; restoreMonster(monst, NULL, NULL); - //DEBUG printf("\nPlaced a creature (%s) at (%i, %i).", monst->info.monsterName, monst->loc.x, monst->loc.y); + // DEBUG printf("\nPlaced a creature (%s) at (%i, %i).", monst->info.monsterName, monst->loc.x, monst->loc.y); monst->ticksUntilTurn = monst->movementSpeed; refreshDungeonCell(monst->loc.x, monst->loc.y); @@ -1956,8 +1841,7 @@ void monstersApproachStairs() { } } - if (rogue.yendorWarden - && abs(rogue.depthLevel - rogue.yendorWarden->depth) > 1) { + if (rogue.yendorWarden && abs(rogue.depthLevel - rogue.yendorWarden->depth) > 1) { updateYendorWardenTracking(); } @@ -2093,26 +1977,15 @@ void autoRest() { // Stop as soon as we're free from crystal. const boolean initiallyEmbedded = cellHasTerrainFlag(player.loc.x, player.loc.y, T_OBSTRUCTS_PASSABILITY); - if ((player.currentHP < player.info.maxHP - || player.status[STATUS_HALLUCINATING] - || player.status[STATUS_CONFUSED] - || player.status[STATUS_NAUSEOUS] - || player.status[STATUS_POISONED] - || player.status[STATUS_DARKNESS] + if ((player.currentHP < player.info.maxHP || player.status[STATUS_HALLUCINATING] || player.status[STATUS_CONFUSED] || player.status[STATUS_NAUSEOUS] || player.status[STATUS_POISONED] || player.status[STATUS_DARKNESS] || initiallyEmbedded) && !rogue.disturbed) { int i = 0; while (i++ < TURNS_FOR_FULL_REGEN - && (player.currentHP < player.info.maxHP - || player.status[STATUS_HALLUCINATING] - || player.status[STATUS_CONFUSED] - || player.status[STATUS_NAUSEOUS] - || player.status[STATUS_POISONED] - || player.status[STATUS_DARKNESS] + && (player.currentHP < player.info.maxHP || player.status[STATUS_HALLUCINATING] || player.status[STATUS_CONFUSED] || player.status[STATUS_NAUSEOUS] || player.status[STATUS_POISONED] || player.status[STATUS_DARKNESS] || cellHasTerrainFlag(player.loc.x, player.loc.y, T_OBSTRUCTS_PASSABILITY)) - && !rogue.disturbed - && (!initiallyEmbedded || cellHasTerrainFlag(player.loc.x, player.loc.y, T_OBSTRUCTS_PASSABILITY))) { + && !rogue.disturbed && (!initiallyEmbedded || cellHasTerrainFlag(player.loc.x, player.loc.y, T_OBSTRUCTS_PASSABILITY))) { recordKeystroke(REST_KEY, false, false); rogue.justRested = true; @@ -2122,7 +1995,7 @@ void autoRest() { } } } else { - for (int i=0; i<100 && !rogue.disturbed; i++) { + for (int i = 0; i < 100 && !rogue.disturbed; i++) { recordKeystroke(REST_KEY, false, false); rogue.justRested = true; playerTurnEnded(); @@ -2175,9 +2048,7 @@ void manualSearch() { // Call this periodically (when haste/slow wears off and when moving between depths) // to keep environmental updates in sync with player turns. -void synchronizePlayerTimeState() { - rogue.ticksTillUpdateEnvironment = player.ticksUntilTurn; -} +void synchronizePlayerTimeState() { rogue.ticksTillUpdateEnvironment = player.ticksUntilTurn; } void playerRecoversFromAttacking(boolean anAttackHit) { if (player.ticksUntilTurn >= 0) { @@ -2192,7 +2063,6 @@ void playerRecoversFromAttacking(boolean anAttackHit) { } } - static void recordCurrentCreatureHealths() { boolean handledPlayer = false; @@ -2252,7 +2122,7 @@ void playerTurnEnded() { resetScentTurnNumber(); } - //updateFlavorText(); + // updateFlavorText(); // Regeneration/starvation: if (player.status[STATUS_NUTRITION] <= 0) { @@ -2261,8 +2131,7 @@ void playerTurnEnded() { gameOver("Starved to death", true); return; } - } else if (player.currentHP < player.info.maxHP - && !player.status[STATUS_POISONED]) { + } else if (player.currentHP < player.info.maxHP && !player.status[STATUS_POISONED]) { if ((player.turnsUntilRegen -= 1000) <= 0) { player.currentHP++; if (player.previousHealthPoints < player.currentHP) { @@ -2293,9 +2162,7 @@ void playerTurnEnded() { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); - if ((monst->bookkeepingFlags & MB_BOUND_TO_LEADER) - && (!monst->leader || !(monst->bookkeepingFlags & MB_FOLLOWER)) - && (monst->creatureState != MONSTER_ALLY)) { + if ((monst->bookkeepingFlags & MB_BOUND_TO_LEADER) && (!monst->leader || !(monst->bookkeepingFlags & MB_FOLLOWER)) && (monst->creatureState != MONSTER_ALLY)) { killCreature(monst, false); if (canSeeMonster(monst)) { @@ -2335,14 +2202,14 @@ void playerTurnEnded() { } updateScent(); -// updateVision(true); -// rogue.stealthRange = currentStealthRange(); -// if (rogue.displayStealthRangeMode) { -// displayLevel(); -// } - rogue.updatedSafetyMapThisTurn = false; - rogue.updatedAllySafetyMapThisTurn = false; - rogue.updatedMapToSafeTerrainThisTurn = false; + // updateVision(true); + // rogue.stealthRange = currentStealthRange(); + // if (rogue.displayStealthRangeMode) { + // displayLevel(); + // } + rogue.updatedSafetyMapThisTurn = false; + rogue.updatedAllySafetyMapThisTurn = false; + rogue.updatedMapToSafeTerrainThisTurn = false; for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); @@ -2382,8 +2249,8 @@ void playerTurnEnded() { // stuff that happens periodically according to an objective time measurement goes here: rechargeItemsIncrementally(1); // staffs recharge every so often - processIncrementalAutoID(); // become more familiar with worn armor and rings - rogue.monsterSpawnFuse--; // monsters spawn in the level every so often + processIncrementalAutoID(); // become more familiar with worn armor and rings + rogue.monsterSpawnFuse--; // monsters spawn in the level every so often for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); @@ -2399,15 +2266,14 @@ void playerTurnEnded() { for (creatureIterator it = iterateCreatures(monsters); hasNextCreature(it);) { creature *monst = nextCreature(&it); - if (monst->info.DFChance - && !(monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) - && rand_percent(monst->info.DFChance)) { + if (monst->info.DFChance && !(monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) && rand_percent(monst->info.DFChance)) { spawnDungeonFeature(monst->loc.x, monst->loc.y, &dungeonFeatureCatalog[monst->info.DFType], true, false); } } - updateEnvironment(); // Update fire and gas, items floating around in water, monsters falling into chasms, etc. + updateEnvironment(); // Update fire and gas, items floating around in water, monsters falling into + // chasms, etc. decrementPlayerStatus(); applyInstantTileEffectsToCreature(&player); if (rogue.gameHasEnded) { // caustic gas, lava, trapdoor, etc. @@ -2434,10 +2300,7 @@ void playerTurnEnded() { monst->currentHP = monst->info.maxHP; } - if ((monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) - || monst->status[STATUS_PARALYZED] - || monst->status[STATUS_ENTRANCED] - || (monst->bookkeepingFlags & MB_CAPTIVE)) { + if ((monst->info.flags & MONST_GETS_TURN_ON_ACTIVATION) || monst->status[STATUS_PARALYZED] || monst->status[STATUS_ENTRANCED] || (monst->bookkeepingFlags & MB_CAPTIVE)) { // Do not pass go; do not collect 200 gold. monst->ticksUntilTurn = monst->movementSpeed; @@ -2462,7 +2325,7 @@ void playerTurnEnded() { } } // DEBUG displayLevel(); - //checkForDungeonErrors(); + // checkForDungeonErrors(); updateVision(true); rogue.stealthRange = currentStealthRange(); @@ -2478,12 +2341,9 @@ void playerTurnEnded() { if (rogue.cautiousMode || rogue.automationActive) { oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC; - //assureCosmeticRNG; + // assureCosmeticRNG; monsterName(buf2, monst, false); - sprintf(buf, "you %s a%s %s", - playerCanDirectlySee(monst->loc.x, monst->loc.y) ? "see" : "sense", - (isVowelish(buf2) ? "n" : ""), - buf2); + sprintf(buf, "you %s a%s %s", playerCanDirectlySee(monst->loc.x, monst->loc.y) ? "see" : "sense", (isVowelish(buf2) ? "n" : ""), buf2); if (rogue.cautiousMode) { strcat(buf, "."); message(buf, REQUIRE_ACKNOWLEDGMENT); @@ -2497,26 +2357,19 @@ void playerTurnEnded() { if (canSeeMonster(monst)) { monst->bookkeepingFlags |= MB_WAS_VISIBLE; - if (cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY) - && cellHasTMFlag(monst->loc.x, monst->loc.y, TM_IS_SECRET)) { + if (cellHasTerrainFlag(monst->loc.x, monst->loc.y, T_OBSTRUCTS_PASSABILITY) && cellHasTMFlag(monst->loc.x, monst->loc.y, TM_IS_SECRET)) { discover(monst->loc.x, monst->loc.y); } if (canDirectlySeeMonster(monst)) { - if (rogue.weapon && rogue.weapon->flags & ITEM_RUNIC - && rogue.weapon->enchant2 == W_SLAYING - && !(rogue.weapon->flags & ITEM_RUNIC_HINTED) - && monsterIsInClass(monst, rogue.weapon->vorpalEnemy)) { + if (rogue.weapon && rogue.weapon->flags & ITEM_RUNIC && rogue.weapon->enchant2 == W_SLAYING && !(rogue.weapon->flags & ITEM_RUNIC_HINTED) && monsterIsInClass(monst, rogue.weapon->vorpalEnemy)) { rogue.weapon->flags |= ITEM_RUNIC_HINTED; itemName(rogue.weapon, buf2, false, false, NULL); sprintf(buf, "the runes on your %s gleam balefully.", buf2); messageWithColor(buf, &itemMessageColor, REQUIRE_ACKNOWLEDGMENT); } - if (rogue.armor && rogue.armor->flags & ITEM_RUNIC - && rogue.armor->enchant2 == A_IMMUNITY - && !(rogue.armor->flags & ITEM_RUNIC_HINTED) - && monsterIsInClass(monst, rogue.armor->vorpalEnemy)) { + if (rogue.armor && rogue.armor->flags & ITEM_RUNIC && rogue.armor->enchant2 == A_IMMUNITY && !(rogue.armor->flags & ITEM_RUNIC_HINTED) && monsterIsInClass(monst, rogue.armor->vorpalEnemy)) { rogue.armor->flags |= ITEM_RUNIC_HINTED; itemName(rogue.armor, buf2, false, false, NULL); @@ -2526,9 +2379,7 @@ void playerTurnEnded() { } } - if (!canSeeMonster(monst) - && (monst->bookkeepingFlags & MB_WAS_VISIBLE) - && !(monst->bookkeepingFlags & MB_CAPTIVE)) { + if (!canSeeMonster(monst) && (monst->bookkeepingFlags & MB_WAS_VISIBLE) && !(monst->bookkeepingFlags & MB_CAPTIVE)) { // For captives we never unset MB_WAS_VISIBLE because captives are not moving, // so we don't want to get "You see a ..." every time they come back into view. @@ -2544,7 +2395,7 @@ void playerTurnEnded() { } } - //checkNutrition(); // Now handled within decrementPlayerStatus(). + // checkNutrition(); // Now handled within decrementPlayerStatus(). if (!rogue.playbackFastForward) { shuffleTerrainColors(100, false); } @@ -2591,8 +2442,7 @@ void playerTurnEnded() { if (turnsRequiredToShore == turnsToShore || turnsRequiredToShore + 1 == turnsToShore) { message("better head back to solid ground!", REQUIRE_ACKNOWLEDGMENT); rogue.receivedLevitationWarning = true; - } else if (turnsRequiredToShore > turnsToShore - && turnsRequiredToShore < 10000) { + } else if (turnsRequiredToShore > turnsToShore && turnsRequiredToShore < 10000) { message("you're past the point of no return!", REQUIRE_ACKNOWLEDGMENT); rogue.receivedLevitationWarning = true; } @@ -2617,8 +2467,8 @@ void resetScentTurnNumber() { // don't want player.scentTurnNumber to roll over rogue.scentTurnNumber -= 15000; for (d = 0; d < gameConst->deepestLevel; d++) { if (levels[d].visited) { - for (i=0; i 15000) { levels[d].scentMap[i][j] -= 15000; } else { diff --git a/src/brogue/Utilities.c b/src/brogue/Utilities.c index ac976299..ddcc4008 100644 --- a/src/brogue/Utilities.c +++ b/src/brogue/Utilities.c @@ -23,8 +23,7 @@ #include "Rogue.h" // String Functions -boolean endswith(const char *str, const char *ending) -{ +boolean endswith(const char *str, const char *ending) { int str_len = strlen(str), ending_len = strlen(ending); if (str_len < ending_len) return false; return strcmp(str + str_len - ending_len, ending) == 0 ? true : false; diff --git a/src/brogue/Wizard.c b/src/brogue/Wizard.c index 1288a6a9..31d9c545 100644 --- a/src/brogue/Wizard.c +++ b/src/brogue/Wizard.c @@ -28,28 +28,24 @@ void initializeCreateItemButton(brogueButton *button, char *text) { char buttonText[COLS * 3]; initializeButton(button); - strcpy(buttonText,text); + strcpy(buttonText, text); upperCase(buttonText); - strcpy(button->text,buttonText); + strcpy(button->text, buttonText); } #define DIALOG_CREATE_ITEM_MAX_BUTTONS 26 // Display a dialog window for the user to select a single entry from a list -static short dialogSelectEntryFromList( - brogueButton *buttons, - short buttonCount, - char *windowTitle -) { +static short dialogSelectEntryFromList(brogueButton *buttons, short buttonCount, char *windowTitle) { - short x=0, y=0, width=0, height=0; + short x = 0, y = 0, width = 0, height = 0; cellDisplayBuffer dbuf[COLS][ROWS], rbuf[COLS][ROWS]; short i, selectedButton, len, maxLen; char buttonText[COLS]; maxLen = strlen(windowTitle); - for (i=0; i < buttonCount; i++) { + for (i = 0; i < buttonCount; i++) { buttons[i].flags &= ~(B_WIDE_CLICK_AREA | B_GRADIENT); buttons[i].buttonColor = interfaceBoxColor; buttons[i].hotkey[0] = 'a' + i; @@ -72,15 +68,15 @@ static short dialogSelectEntryFromList( y = WINDOW_POSITION_DUNGEON_TOP_LEFT.window_y; clearDisplayBuffer(dbuf); - //Dialog Title - printString(windowTitle, x , y - 1, &itemMessageColor, &interfaceBoxColor, dbuf); - //Dialog background + // Dialog Title + printString(windowTitle, x, y - 1, &itemMessageColor, &interfaceBoxColor, dbuf); + // Dialog background rectangularShading(x - 1, y - 1, width + 1, height + 1, &interfaceBoxColor, INTERFACE_OPACITY, dbuf); - //Display the title/background and save the prior display state + // Display the title/background and save the prior display state overlayDisplayBuffer(dbuf, rbuf); - //Display the buttons and wait for user selection + // Display the buttons and wait for user selection selectedButton = buttonInputLoop(buttons, buttonCount, x, y, width, height, NULL); - //Revert the display state + // Revert the display state overlayDisplayBuffer(rbuf, NULL); return selectedButton; @@ -93,7 +89,7 @@ static short dialogCreateItemChooseVorpalEnemy() { brogueButton buttons[DIALOG_CREATE_ITEM_MAX_BUTTONS]; for (i = 0; i < MONSTER_CLASS_COUNT; i++) { - strcpy(buttonText,monsterClassCatalog[i].name); + strcpy(buttonText, monsterClassCatalog[i].name); initializeCreateItemButton(&(buttons[i]), buttonText); } @@ -102,9 +98,9 @@ static short dialogCreateItemChooseVorpalEnemy() { // Display a dialog window for the user to select a runic for the given armor or weapon. // Assigns the selected runic and vorpal enemy (if applicable) to the item. No return value. -static void dialogCreateItemChooseRunic(item *theItem){ +static void dialogCreateItemChooseRunic(item *theItem) { char buttonText[COLS]; - short i=0, runicOffset =0, noRunic, selectedRunic, selectedVorpalEnemy; + short i = 0, runicOffset = 0, noRunic, selectedRunic, selectedVorpalEnemy; brogueButton buttons[DIALOG_CREATE_ITEM_MAX_BUTTONS]; if (!(theItem->category & (WEAPON | ARMOR))) { @@ -116,14 +112,14 @@ static void dialogCreateItemChooseRunic(item *theItem){ // to the kind (itemtable). if (theItem->category == WEAPON) { if (theItem->kind == HAMMER || theItem->kind == WAR_AXE || theItem->kind == PIKE || theItem->kind == BROADSWORD) { - for (i=0; iquiverNumber == 0) { - for (i=0; icategory == ARMOR) { - if (theItem->kind == PLATE_MAIL) { //bad runics only - for (i=0; ikind == PLATE_MAIL) { // bad runics only + for (i = 0; i < NUMBER_ARMOR_ENCHANT_KINDS - NUMBER_GOOD_ARMOR_ENCHANT_KINDS; i++) { strcpy(buttonText, armorRunicNames[i + NUMBER_GOOD_ARMOR_ENCHANT_KINDS]); initializeCreateItemButton(&(buttons[i]), buttonText); } runicOffset = NUMBER_GOOD_ARMOR_ENCHANT_KINDS; } else { - for (i=0; i=0 && selectedRunic != noRunic) { + if (selectedRunic >= 0 && selectedRunic != noRunic) { theItem->enchant2 = selectedRunic + runicOffset; theItem->flags |= ITEM_RUNIC; - if ((theItem->enchant2 == W_SLAYING && theItem->category == WEAPON) - || (theItem->enchant2 == A_IMMUNITY && theItem->category == ARMOR)) { + if ((theItem->enchant2 == W_SLAYING && theItem->category == WEAPON) || (theItem->enchant2 == A_IMMUNITY && theItem->category == ARMOR)) { selectedVorpalEnemy = dialogCreateItemChooseVorpalEnemy(); - if (selectedVorpalEnemy >=0) { + if (selectedVorpalEnemy >= 0) { theItem->vorpalEnemy = selectedVorpalEnemy; } else { // remove the runic if no vorpal enemy chosen theItem->enchant2 = 0; @@ -183,12 +178,12 @@ static short dialogCreateItemChooseKind(enum itemCategory category) { kindTable = tableForItemCategory(category); kindCount = itemKindCount(category, 0); - for (i=0; ienchant1; @@ -215,15 +210,14 @@ static void dialogCreateItemChooseEnchantmentLevel(item *theItem) { if (!(theItem->flags & ITEM_RUNIC)) { minVal = -3; } else { // bad runics can only be negatively enchanted - if ((theItem->category == ARMOR && theItem->enchant2 >= NUMBER_GOOD_ARMOR_ENCHANT_KINDS) - || (theItem->category == WEAPON && theItem->enchant2 >= NUMBER_GOOD_WEAPON_ENCHANT_KINDS)) { + if ((theItem->category == ARMOR && theItem->enchant2 >= NUMBER_GOOD_ARMOR_ENCHANT_KINDS) || (theItem->category == WEAPON && theItem->enchant2 >= NUMBER_GOOD_WEAPON_ENCHANT_KINDS)) { minVal = -3; maxVal = -1; - theItem->enchant1 = rand_range(-3,-1); + theItem->enchant1 = rand_range(-3, -1); } else { // good runics can only be positively enchanted minVal = 1; if (theItem->enchant1 < 1) { - theItem->enchant1 = rand_range(1,3); + theItem->enchant1 = rand_range(1, 3); } } defaultVal = theItem->enchant1; @@ -235,10 +229,10 @@ static void dialogCreateItemChooseEnchantmentLevel(item *theItem) { // Validate the input int enchants; - if (strlen(inputBuf) // we need some input - && sscanf(inputBuf, "%d", &enchants) // try to convert to number - && sprintf(buf, "%d", enchants) // convert back to string - && strcmp(buf, inputBuf) == 0) { // compare (0 if equal) + if (strlen(inputBuf) // we need some input + && sscanf(inputBuf, "%d", &enchants) // try to convert to number + && sprintf(buf, "%d", enchants) // convert back to string + && strcmp(buf, inputBuf) == 0) { // compare (0 if equal) // handle out of range input if (enchants > maxVal) { enchants = maxVal; @@ -261,14 +255,14 @@ static void dialogCreateItemChooseEnchantmentLevel(item *theItem) { } } -static int creatureTypeCompareMonsterNames (const void * a, const void * b) { +static int creatureTypeCompareMonsterNames(const void *a, const void *b) { creatureType *c1 = (creatureType *)a; creatureType *c2 = (creatureType *)b; char name1[COLS]; char name2[COLS]; - strncpy(name1,c1->monsterName,COLS); - strncpy(name2,c2->monsterName,COLS); + strncpy(name1, c1->monsterName, COLS); + strncpy(name2, c2->monsterName, COLS); upperCase(name1); upperCase(name2); @@ -281,9 +275,8 @@ static void dialogCreateMonsterChooseMutation(creature *theMonster) { short i, j = 0, noMutation, selectedMutation; brogueButton buttons[DIALOG_CREATE_ITEM_MAX_BUTTONS]; - for (i=0; iinfo.flags & mutationCatalog[i].forbiddenFlags) - && !(theMonster->info.abilityFlags & mutationCatalog[i].forbiddenAbilityFlags)) { + for (i = 0; i < NUMBER_MUTATORS; i++) { + if (!(theMonster->info.flags & mutationCatalog[i].forbiddenFlags) && !(theMonster->info.abilityFlags & mutationCatalog[i].forbiddenAbilityFlags)) { strncpy(buttonText, mutationCatalog[i].title, COLS); initializeCreateItemButton(&(buttons[j]), buttonText); j++; @@ -293,7 +286,7 @@ static void dialogCreateMonsterChooseMutation(creature *theMonster) { initializeCreateItemButton(&(buttons[j]), "No mutation"); noMutation = j; - selectedMutation = dialogSelectEntryFromList(buttons, j+1, "Choose a mutation:"); + selectedMutation = dialogSelectEntryFromList(buttons, j + 1, "Choose a mutation:"); if (selectedMutation != noMutation) { mutateMonster(theMonster, selectedMutation); @@ -306,7 +299,7 @@ static void dialogCreateMonster() { char buttonText[COLS]; pos selectedPosition; boolean locationIsValid = true; - short i, j=0, selectedMonster, monsterOffset, buttonCount=0; + short i, j = 0, selectedMonster, monsterOffset, buttonCount = 0; const short MONSTERS_PER_PAGE = 24; const short CREATABLE_MONSTER_KINDS = NUMBER_MONSTER_KINDS - 2; char theMessage[COLS] = ""; @@ -317,7 +310,7 @@ static void dialogCreateMonster() { // There are too many monsters to fit on a page so we break them into ranges. First we copy the monster catalog and // sort it alphabetically by name. Also, we exclude creation of lich and phoenix as those are summoned by phylactery // and phoenix egg respectively. - for (i=0; i < NUMBER_MONSTER_KINDS; i++) { + for (i = 0; i < NUMBER_MONSTER_KINDS; i++) { if (!(monsterCatalog[i].monsterID == MK_LICH) && !(monsterCatalog[i].monsterID == MK_PHOENIX)) { monsterKinds[j] = monsterCatalog[i]; upperCase(monsterKinds[j].monsterName); @@ -325,13 +318,13 @@ static void dialogCreateMonster() { } } - qsort(monsterKinds,CREATABLE_MONSTER_KINDS,sizeof(creatureType),&creatureTypeCompareMonsterNames); + qsort(monsterKinds, CREATABLE_MONSTER_KINDS, sizeof(creatureType), &creatureTypeCompareMonsterNames); - for (i=0; i < CREATABLE_MONSTER_KINDS; i+=MONSTERS_PER_PAGE) { + for (i = 0; i < CREATABLE_MONSTER_KINDS; i += MONSTERS_PER_PAGE) { if (i + MONSTERS_PER_PAGE < CREATABLE_MONSTER_KINDS) { - sprintf(monsterRangeText,"%s - %s",monsterKinds[i].monsterName, monsterKinds[i + MONSTERS_PER_PAGE-1].monsterName); + sprintf(monsterRangeText, "%s - %s", monsterKinds[i].monsterName, monsterKinds[i + MONSTERS_PER_PAGE - 1].monsterName); } else { - sprintf(monsterRangeText,"%s - %s",monsterKinds[i].monsterName, monsterKinds[CREATABLE_MONSTER_KINDS-1].monsterName); + sprintf(monsterRangeText, "%s - %s", monsterKinds[i].monsterName, monsterKinds[CREATABLE_MONSTER_KINDS - 1].monsterName); } initializeCreateItemButton(&(buttons[buttonCount]), monsterRangeText); buttonCount++; @@ -342,11 +335,11 @@ static void dialogCreateMonster() { if (monsterOffset == -1) { return; } - monsterOffset*= MONSTERS_PER_PAGE; + monsterOffset *= MONSTERS_PER_PAGE; // populate menu of monsters in the selected range buttonCount = 0; - for (i=monsterOffset; i < monsterOffset + MONSTERS_PER_PAGE && i < CREATABLE_MONSTER_KINDS; i++) { + for (i = monsterOffset; i < monsterOffset + MONSTERS_PER_PAGE && i < CREATABLE_MONSTER_KINDS; i++) { strncpy(buttonText, monsterKinds[i].monsterName, COLS); initializeCreateItemButton(&(buttons[buttonCount]), buttonText); buttonCount++; @@ -358,7 +351,7 @@ static void dialogCreateMonster() { return; } - selectedMonster+= monsterOffset; + selectedMonster += monsterOffset; theMonster = generateMonster(monsterKinds[selectedMonster].monsterID, false, false); @@ -410,10 +403,7 @@ static void dialogCreateMonster() { refreshSideBar(-1, -1, false); refreshDungeonCell(theMonster->loc.x, theMonster->loc.y); - if (!(theMonster->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) - || theMonster->info.monsterID == MK_PHOENIX_EGG - || theMonster->info.monsterID == MK_PHYLACTERY - ) { + if (!(theMonster->info.flags & (MONST_INANIMATE | MONST_INVULNERABLE)) || theMonster->info.monsterID == MK_PHOENIX_EGG || theMonster->info.monsterID == MK_PHYLACTERY) { sprintf(theMessage, "Make the %s your ally?", theMonster->info.monsterName); if (confirm(theMessage, false)) { becomeAllyWith(theMonster); @@ -425,7 +415,7 @@ static void dialogCreateMonster() { sprintf(theMessage, "%s created.", theMonster->info.monsterName); } message(theMessage, 0); - } else { // no location chosen + } else { // no location chosen confirmMessages(); killCreature(theMonster, true); removeDeadMonsters(); @@ -440,14 +430,14 @@ static void dialogCreateItem() { short i, selectedCategory, selectedKind; char message[COLS] = ""; item *theItem; - char theItemName[100]=""; + char theItemName[100] = ""; if (numberOfItemsInPack() == MAX_PACK_ITEMS) { messageWithColor("Your pack is already full.", &itemMessageColor, 0); return; } - for (i=0; i < NUMBER_ITEM_CATEGORIES; i++) { + for (i = 0; i < NUMBER_ITEM_CATEGORIES; i++) { strncpy(buttonText, itemCategoryNames[i], COLS); initializeCreateItemButton(&(buttons[i]), buttonText); } @@ -486,7 +476,7 @@ static void dialogCreateItem() { dialogCreateItemChooseRunic(theItem); } - if (Fl(selectedCategory) & CAN_BE_ENCHANTED && theItem->quiverNumber == 0) { + if (Fl(selectedCategory) & CAN_BE_ENCHANTED && theItem->quiverNumber == 0) { dialogCreateItemChooseEnchantmentLevel(theItem); } @@ -499,7 +489,7 @@ static void dialogCreateItem() { theItem = addItemToPack(theItem); itemName(theItem, theItemName, true, true, NULL); - sprintf(message,"you now have %s (%c).", theItemName, theItem->inventoryLetter); + sprintf(message, "you now have %s (%c).", theItemName, theItem->inventoryLetter); messageWithColor(message, &itemMessageColor, 0); } diff --git a/src/platform/PlatformDefines.h b/src/platform/PlatformDefines.h index d69ab3a8..69129621 100644 --- a/src/platform/PlatformDefines.h +++ b/src/platform/PlatformDefines.h @@ -25,5 +25,4 @@ // should go in here. #define BROGUE_LIBTCOD -#define PLAY_AGAIN_STRING "Press space to play again." - +#define PLAY_AGAIN_STRING "Press space to play again." diff --git a/src/platform/curses-platform.c b/src/platform/curses-platform.c index a7540586..ba365ddd 100644 --- a/src/platform/curses-platform.c +++ b/src/platform/curses-platform.c @@ -24,35 +24,64 @@ static char glyphToAscii(enum displayGlyph glyph) { unsigned int ch; switch (glyph) { - case G_UP_ARROW: return '^'; - case G_DOWN_ARROW: return 'v'; - case G_FLOOR: return '.'; - case G_CHASM: return ':'; - case G_TRAP: return '%'; - case G_FIRE: return '^'; - case G_FOLIAGE: return '&'; - case G_AMULET: return ','; - case G_SCROLL: return '?'; - case G_RING: return '='; - case G_WEAPON: return '('; - case G_GEM: return '+'; - case G_TOTEM: return '0'; // zero - case G_GOOD_MAGIC: return '$'; - case G_BAD_MAGIC: return '+'; - case G_DOORWAY: return '<'; - case G_CHARM: return '7'; - case G_GUARDIAN: return '5'; - case G_WINGED_GUARDIAN: return '5'; - case G_EGG: return 'o'; - case G_BLOODWORT_STALK: return '&'; - case G_FLOOR_ALT: return '.'; - case G_UNICORN: return 'U'; - case G_TURRET: return '*'; - case G_CARPET: return '.'; - case G_STATUE: return '5'; - case G_CRACKED_STATUE: return '5'; - case G_MAGIC_GLYPH: return ':'; - case G_ELECTRIC_CRYSTAL: return '$'; + case G_UP_ARROW: + return '^'; + case G_DOWN_ARROW: + return 'v'; + case G_FLOOR: + return '.'; + case G_CHASM: + return ':'; + case G_TRAP: + return '%'; + case G_FIRE: + return '^'; + case G_FOLIAGE: + return '&'; + case G_AMULET: + return ','; + case G_SCROLL: + return '?'; + case G_RING: + return '='; + case G_WEAPON: + return '('; + case G_GEM: + return '+'; + case G_TOTEM: + return '0'; // zero + case G_GOOD_MAGIC: + return '$'; + case G_BAD_MAGIC: + return '+'; + case G_DOORWAY: + return '<'; + case G_CHARM: + return '7'; + case G_GUARDIAN: + return '5'; + case G_WINGED_GUARDIAN: + return '5'; + case G_EGG: + return 'o'; + case G_BLOODWORT_STALK: + return '&'; + case G_FLOOR_ALT: + return '.'; + case G_UNICORN: + return 'U'; + case G_TURRET: + return '*'; + case G_CARPET: + return '.'; + case G_STATUE: + return '5'; + case G_CRACKED_STATUE: + return '5'; + case G_MAGIC_GLYPH: + return ':'; + case G_ELECTRIC_CRYSTAL: + return '$'; default: ch = glyphToUnicode(glyph); @@ -61,20 +90,17 @@ static char glyphToAscii(enum displayGlyph glyph) { } } -static void curses_plotChar(enum displayGlyph ch, - short xLoc, short yLoc, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue) { +static void curses_plotChar(enum displayGlyph ch, short xLoc, short yLoc, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue) { fcolor fore; fcolor back; - fore.r = (float) foreRed / 100; - fore.g = (float) foreGreen / 100; - fore.b = (float) foreBlue / 100; - back.r = (float) backRed / 100; - back.g = (float) backGreen / 100; - back.b = (float) backBlue / 100; + fore.r = (float)foreRed / 100; + fore.g = (float)foreGreen / 100; + fore.b = (float)foreBlue / 100; + back.r = (float)backRed / 100; + back.g = (float)backGreen / 100; + back.b = (float)backBlue / 100; ch = glyphToAscii(ch); @@ -82,7 +108,6 @@ static void curses_plotChar(enum displayGlyph ch, Term.put(xLoc, yLoc, ch, &fore, &back); } - struct mapsymbol { int in_c, out_c; struct mapsymbol *next; @@ -104,8 +129,7 @@ static int rewriteKey(int key, boolean text) { return key; } - -#define PAUSE_BETWEEN_EVENT_POLLING 34//17 +#define PAUSE_BETWEEN_EVENT_POLLING 34 // 17 static uint64_t getTime() { struct timeval tv; @@ -130,7 +154,7 @@ static void curses_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInpu Term.refresh(); for (;;) { - theTime = getTime(); //TCOD_sys_elapsed_milli(); + theTime = getTime(); // TCOD_sys_elapsed_milli(); /*if (TCOD_console_is_window_closed()) { rogue.gameHasEnded = true; // causes the game loop to terminate quickly @@ -144,7 +168,6 @@ static void curses_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInpu commitDraws(); } - key = Term.getkey(); if (key == TERM_MOUSE) { if (Term.mouse.x > 0 && Term.mouse.y > 0 && Term.mouse.x < COLS && Term.mouse.y < ROWS) { @@ -163,20 +186,24 @@ static void curses_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInpu returnEvent->eventType = KEYSTROKE; returnEvent->controlKey = Term.ctrlPressed(&key); //(key.rctrl || key.lctrl); - returnEvent->shiftKey = 0; //key.shift; + returnEvent->shiftKey = 0; // key.shift; returnEvent->param1 = key; - if (key == Term.keys.backspace || key == Term.keys.del) returnEvent->param1 = DELETE_KEY; - else if (key == Term.keys.up) returnEvent->param1 = UP_ARROW; - else if (key == Term.keys.down) returnEvent->param1 = DOWN_ARROW; - else if (key == Term.keys.left) returnEvent->param1 = LEFT_ARROW; - else if (key == Term.keys.right) returnEvent->param1 = RIGHT_ARROW; + if (key == Term.keys.backspace || key == Term.keys.del) + returnEvent->param1 = DELETE_KEY; + else if (key == Term.keys.up) + returnEvent->param1 = UP_ARROW; + else if (key == Term.keys.down) + returnEvent->param1 = DOWN_ARROW; + else if (key == Term.keys.left) + returnEvent->param1 = LEFT_ARROW; + else if (key == Term.keys.right) + returnEvent->param1 = RIGHT_ARROW; else if (key == Term.keys.quit) { rogue.gameHasEnded = true; rogue.gameExitStatusCode = EXIT_STATUS_SUCCESS; rogue.nextGame = NG_QUIT; // causes the menu to drop out immediately - } - else if ((key >= 'A' && key <= 'Z')) { + } else if ((key >= 'A' && key <= 'Z')) { returnEvent->shiftKey = 1; // returnEvent->param1 += 'a' - 'A'; } @@ -209,18 +236,6 @@ static void curses_remap(const char *input_name, const char *output_name) { keymap = sym; } -static boolean modifier_held(int modifier) { - return 0; -} +static boolean modifier_held(int modifier) { return 0; } -struct brogueConsole cursesConsole = { - gameLoop, - curses_pauseForMilliseconds, - curses_nextKeyOrMouseEvent, - curses_plotChar, - curses_remap, - modifier_held, - NULL, - NULL, - NULL -}; +struct brogueConsole cursesConsole = {gameLoop, curses_pauseForMilliseconds, curses_nextKeyOrMouseEvent, curses_plotChar, curses_remap, modifier_held, NULL, NULL, NULL}; diff --git a/src/platform/main.c b/src/platform/main.c index 6510781a..bddbc220 100644 --- a/src/platform/main.c +++ b/src/platform/main.c @@ -17,38 +17,36 @@ enum graphicsModes graphicsMode = TEXT_GRAPHICS; boolean isCsvFormat = false; static void printCommandlineHelp() { - printf("%s", - "--help -h print this help message and exit \n" - "--version -V print the version and exit\n" - "--scores dump scores to output and exit\n" - "-n start a new game, skipping the menu\n" - "-s seed start a new game with the specified numerical seed\n" - "-o filename[.broguesave] open a save file (extension optional)\n" - "-v recording[.broguerec] view a recording (extension optional)\n" - "-vn recording[.broguerec] view a recording non-interactively (extension optional)\n" + printf("%s", "--help -h print this help message and exit \n" + "--version -V print the version and exit\n" + "--scores dump scores to output and exit\n" + "-n start a new game, skipping the menu\n" + "-s seed start a new game with the specified numerical seed\n" + "-o filename[.broguesave] open a save file (extension optional)\n" + "-v recording[.broguerec] view a recording (extension optional)\n" + "-vn recording[.broguerec] view a recording non-interactively (extension optional)\n" #ifdef BROGUE_WEB - "--server-mode run the game in web-brogue server mode\n" + "--server-mode run the game in web-brogue server mode\n" #endif #ifdef BROGUE_SDL - "--size N starts the game at font size N (1 to 20)\n" - "--graphics -G enable graphical tiles\n" - "--hybrid -H enable hybrid graphics\n" - "--full-screen -F enable full screen\n" - "--no-gpu disable hardware-accelerated graphics and HiDPI\n" + "--size N starts the game at font size N (1 to 20)\n" + "--graphics -G enable graphical tiles\n" + "--hybrid -H enable hybrid graphics\n" + "--full-screen -F enable full screen\n" + "--no-gpu disable hardware-accelerated graphics and HiDPI\n" #endif #ifdef BROGUE_CURSES - "--term -t run in ncurses-based terminal mode\n" + "--term -t run in ncurses-based terminal mode\n" #endif - "--variant variant_name run a variant game (options: rapid_brogue)\n" - "--stealth -S display stealth range\n" - "--no-effects -E disable color effects\n" - "--wizard -W run in wizard mode, invincible with powerful items\n" - "[--csv] --print-seed-catalog [START NUM LEVELS]\n" - " (optional csv format)\n" - " prints a catalog of the first LEVELS levels of NUM\n" - " seeds from seed START (defaults: 1 1000 5)\n" - "--data-dir DIRECTORY specify directory containing game resources (experimental)\n" - ); + "--variant variant_name run a variant game (options: rapid_brogue)\n" + "--stealth -S display stealth range\n" + "--no-effects -E disable color effects\n" + "--wizard -W run in wizard mode, invincible with powerful items\n" + "[--csv] --print-seed-catalog [START NUM LEVELS]\n" + " (optional csv format)\n" + " prints a catalog of the first LEVELS levels of NUM\n" + " seeds from seed START (defaults: 1 1000 5)\n" + "--data-dir DIRECTORY specify directory containing game resources (experimental)\n"); return; } @@ -60,10 +58,10 @@ static void badArgument(const char *arg) { boolean tryParseUint64(char *str, uint64_t *num) { unsigned long long n; char buf[100]; - if (strlen(str) // we need some input - && sscanf(str, "%llu", &n) // try to convert to number - && sprintf(buf, "%llu", n) // convert back to string - && !strcmp(buf, str)) { // compare (we need them equal) + if (strlen(str) // we need some input + && sscanf(str, "%llu", &n) // try to convert to number + && sprintf(buf, "%llu", n) // convert back to string + && !strcmp(buf, str)) { // compare (we need them equal) *num = (uint64_t)n; return true; // success } else { @@ -71,11 +69,10 @@ boolean tryParseUint64(char *str, uint64_t *num) { } } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { #if 0 -#define TOD(x) ((double) (x) / FP_FACTOR) +#define TOD(x) ((double)(x) / FP_FACTOR) fixpt y, x1 = 1, x2 = FP_FACTOR * 70 / 100; for (int i=0; i < 10; i++) { y = fp_pow(x2, x1); printf("%.5f ^ %i = %.5f (%lli)\n", TOD(x2), x1, TOD(y), y); @@ -175,7 +172,7 @@ int main(int argc, char *argv[]) continue; } } - + if (strcmp(argv[i], "-vn") == 0) { if (i + 1 < argc) { strncpy(rogue.nextGamePath, argv[i + 1], BROGUE_FILENAME_MAX); @@ -200,8 +197,7 @@ int main(int argc, char *argv[]) // Use converter for the type the next size up, because it returns signed unsigned int numberOfLevels = atol(argv[i + 3]); - if (tryParseUint64(argv[i+1], &startingSeed) && tryParseUint64(argv[i+2], &numberOfSeeds) - && startingSeed > 0 && numberOfLevels <= 40) { + if (tryParseUint64(argv[i + 1], &startingSeed) && tryParseUint64(argv[i + 2], &numberOfSeeds) && startingSeed > 0 && numberOfLevels <= 40) { printSeedCatalog(startingSeed, numberOfSeeds, numberOfLevels, isCsvFormat); return 0; } @@ -222,17 +218,17 @@ int main(int argc, char *argv[]) } if (strcmp(argv[i], "-G") == 0 || strcmp(argv[i], "--graphics") == 0) { - initialGraphics = TILES_GRAPHICS; // we call setGraphicsMode later + initialGraphics = TILES_GRAPHICS; // we call setGraphicsMode later continue; } if (strcmp(argv[i], "-H") == 0 || strcmp(argv[i], "--hybrid") == 0) { - initialGraphics = HYBRID_GRAPHICS; // we call setGraphicsMode later + initialGraphics = HYBRID_GRAPHICS; // we call setGraphicsMode later continue; } - if (strcmp(argv[i], "--csv") == 0 ) { - isCsvFormat = true; // we call printSeedCatalog later + if (strcmp(argv[i], "--csv") == 0) { + isCsvFormat = true; // we call printSeedCatalog later continue; } @@ -269,7 +265,7 @@ int main(int argc, char *argv[]) #endif #ifdef BROGUE_WEB - if(strcmp(argv[i], "--server-mode") == 0) { + if (strcmp(argv[i], "--server-mode") == 0) { currentConsole = webConsole; rogue.nextGame = NG_NEW_GAME; serverMode = true; @@ -328,4 +324,3 @@ int main(int argc, char *argv[]) return 0; } - diff --git a/src/platform/null-platform.c b/src/platform/null-platform.c index b8f4e53d..90085f3e 100644 --- a/src/platform/null-platform.c +++ b/src/platform/null-platform.c @@ -1,36 +1,13 @@ #include "platform.h" -static void null_gameLoop() { - exit(rogueMain()); -} +static void null_gameLoop() { exit(rogueMain()); } -static boolean null_pauseForMilliseconds(short milliseconds) { - return false; -} +static boolean null_pauseForMilliseconds(short milliseconds) { return false; } -static void null_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance) { - return; -} +static void null_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance) { return; } -static void null_plotChar(enum displayGlyph ch, - short xLoc, short yLoc, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue) { - return; -} +static void null_plotChar(enum displayGlyph ch, short xLoc, short yLoc, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue) { return; } -static boolean null_modifier_held(int modifier) { - return false; -} +static boolean null_modifier_held(int modifier) { return false; } -struct brogueConsole nullConsole = { - null_gameLoop, - null_pauseForMilliseconds, - null_nextKeyOrMouseEvent, - null_plotChar, - NULL, - null_modifier_held, - NULL, - NULL, - NULL -}; +struct brogueConsole nullConsole = {null_gameLoop, null_pauseForMilliseconds, null_nextKeyOrMouseEvent, null_plotChar, NULL, null_modifier_held, NULL, NULL, NULL}; diff --git a/src/platform/platform.h b/src/platform/platform.h index 4d76c557..d8530f75 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -1,26 +1,26 @@ #include "Rogue.h" -#define U_MIDDLE_DOT 0x00b7 -#define U_FOUR_DOTS 0x2237 -#define U_DIAMOND 0x25c7 -#define U_FLIPPED_V 0x22CF -#define U_ARIES 0x2648 -#define U_ESZETT 0x00df -#define U_ANKH 0x2640 -#define U_MUSIC_NOTE 0x266A -#define U_CIRCLE 0x26AA -#define U_LIGHTNING_BOLT 0x03DF -#define U_FILLED_CIRCLE 0x25cf -#define U_NEUTER 0x26b2 -#define U_U_ACUTE 0x00da +#define U_MIDDLE_DOT 0x00b7 +#define U_FOUR_DOTS 0x2237 +#define U_DIAMOND 0x25c7 +#define U_FLIPPED_V 0x22CF +#define U_ARIES 0x2648 +#define U_ESZETT 0x00df +#define U_ANKH 0x2640 +#define U_MUSIC_NOTE 0x266A +#define U_CIRCLE 0x26AA +#define U_LIGHTNING_BOLT 0x03DF +#define U_FILLED_CIRCLE 0x25cf +#define U_NEUTER 0x26b2 +#define U_U_ACUTE 0x00da #define U_CURRENCY 0x00A4 -#define U_UP_ARROW 0x2191 -#define U_DOWN_ARROW 0x2193 -#define U_LEFT_ARROW 0x2190 -#define U_RIGHT_ARROW 0x2192 -#define U_OMEGA 0x03A9 -#define U_CIRCLE_BARS 0x29F2 -#define U_FILLED_CIRCLE_BARS 0x29F3 +#define U_UP_ARROW 0x2191 +#define U_DOWN_ARROW 0x2193 +#define U_LEFT_ARROW 0x2190 +#define U_RIGHT_ARROW 0x2192 +#define U_OMEGA 0x03A9 +#define U_CIRCLE_BARS 0x29F2 +#define U_FILLED_CIRCLE_BARS 0x29F3 // #define U_UP_TRIANGLE 0x2206 // #define U_DOWN_TRIANGLE 0x2207 @@ -53,12 +53,7 @@ struct brogueConsole { /* Draw a character at a location with a specific color. */ - void (*plotChar)( - enum displayGlyph inputChar, - short x, short y, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue - ); + void (*plotChar)(enum displayGlyph inputChar, short x, short y, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue); void (*remap)(const char *, const char *); @@ -116,4 +111,3 @@ extern char dataDirectory[]; // defined in brogue extern playerCharacter rogue; - diff --git a/src/platform/platformdependent.c b/src/platform/platformdependent.c index cc09a02b..6fc0147d 100644 --- a/src/platform/platformdependent.c +++ b/src/platform/platformdependent.c @@ -45,18 +45,30 @@ unsigned int glyphToUnicode(enum displayGlyph glyph) { if (glyph < 128) return glyph; switch (glyph) { - case G_UP_ARROW: return U_UP_ARROW; - case G_DOWN_ARROW: return U_DOWN_ARROW; - case G_POTION: return '!'; - case G_GRASS: return '"'; - case G_WALL: return '#'; - case G_DEMON: return '&'; - case G_OPEN_DOOR: return '\''; - case G_GOLD: return '*'; - case G_CLOSED_DOOR: return '+'; - case G_RUBBLE: return ','; - case G_KEY: return '-'; - case G_BOG: return '~'; + case G_UP_ARROW: + return U_UP_ARROW; + case G_DOWN_ARROW: + return U_DOWN_ARROW; + case G_POTION: + return '!'; + case G_GRASS: + return '"'; + case G_WALL: + return '#'; + case G_DEMON: + return '&'; + case G_OPEN_DOOR: + return '\''; + case G_GOLD: + return '*'; + case G_CLOSED_DOOR: + return '+'; + case G_RUBBLE: + return ','; + case G_KEY: + return '-'; + case G_BOG: + return '~'; case G_CHAIN_TOP_LEFT: case G_CHAIN_BOTTOM_RIGHT: return '\\'; @@ -69,116 +81,226 @@ unsigned int glyphToUnicode(enum displayGlyph glyph) { case G_CHAIN_LEFT: case G_CHAIN_RIGHT: return '-'; - case G_FOOD: return ';'; - case G_UP_STAIRS: return '<'; - case G_VENT: return '='; - case G_DOWN_STAIRS: return '>'; - case G_PLAYER: return '@'; - case G_BOG_MONSTER: return 'B'; - case G_CENTAUR: return 'C'; - case G_DRAGON: return 'D'; - case G_FLAMEDANCER: return 'F'; - case G_GOLEM: return 'G'; - case G_TENTACLE_HORROR: return 'H'; - case G_IFRIT: return 'I'; - case G_JELLY: return 'J'; - case G_KRAKEN: return 'K'; - case G_LICH: return 'L'; - case G_NAGA: return 'N'; - case G_OGRE: return 'O'; - case G_PHANTOM: return 'P'; - case G_REVENANT: return 'R'; - case G_SALAMANDER: return 'S'; - case G_TROLL: return 'T'; - case G_UNDERWORM: return 'U'; - case G_VAMPIRE: return 'V'; - case G_WRAITH: return 'W'; - case G_ZOMBIE: return 'Z'; - case G_ARMOR: return '['; - case G_STAFF: return '/'; - case G_WEB: return ':'; - case G_MOUND: return 'a'; - case G_BLOAT: return 'b'; - case G_CENTIPEDE: return 'c'; - case G_DAR_BLADEMASTER: return 'd'; - case G_EEL: return 'e'; - case G_FURY: return 'f'; - case G_GOBLIN: return 'g'; - case G_IMP: return 'i'; - case G_JACKAL: return 'j'; - case G_KOBOLD: return 'k'; - case G_MONKEY: return 'm'; - case G_PIXIE: return 'p'; - case G_RAT: return 'r'; - case G_SPIDER: return 's'; - case G_TOAD: return 't'; - case G_BAT: return 'v'; - case G_WISP: return 'w'; - case G_PHOENIX: return 'P'; - case G_ALTAR: return '|'; - case G_LIQUID: return '~'; - case G_FLOOR: return U_MIDDLE_DOT; - case G_CHASM: return U_FOUR_DOTS; - case G_TRAP: return U_DIAMOND; - case G_FIRE: return U_FLIPPED_V; - case G_FOLIAGE: return U_ARIES; - case G_AMULET: return U_ANKH; - case G_SCROLL: return U_MUSIC_NOTE; - case G_RING: return U_CIRCLE; - case G_WEAPON: return U_UP_ARROW; - case G_GEM: return U_FILLED_CIRCLE; - case G_TOTEM: return U_NEUTER; - case G_GOOD_MAGIC: return U_FILLED_CIRCLE_BARS; - case G_BAD_MAGIC: return U_CIRCLE_BARS; - case G_DOORWAY: return U_OMEGA; - case G_CHARM: return U_LIGHTNING_BOLT; - case G_WALL_TOP: return '#'; - case G_DAR_PRIESTESS: return 'd'; - case G_DAR_BATTLEMAGE: return 'd'; - case G_GOBLIN_MAGIC: return 'g'; - case G_GOBLIN_CHIEFTAN: return 'g'; - case G_OGRE_MAGIC: return 'O'; - case G_GUARDIAN: return U_ESZETT; - case G_WINGED_GUARDIAN: return U_ESZETT; - case G_EGG: return U_FILLED_CIRCLE; - case G_WARDEN: return 'Y'; - case G_DEWAR: return '&'; - case G_ANCIENT_SPIRIT: return 'M'; - case G_LEVER: return '/'; - case G_LEVER_PULLED: return '\\'; - case G_BLOODWORT_STALK: return U_ARIES; - case G_FLOOR_ALT: return U_MIDDLE_DOT; - case G_UNICORN: return U_U_ACUTE; - case G_TURRET: return U_FILLED_CIRCLE; - case G_WAND: return '~'; - case G_GRANITE: return '#'; - case G_CARPET: return U_MIDDLE_DOT; - case G_CLOSED_IRON_DOOR: return '+'; - case G_OPEN_IRON_DOOR: return '\''; - case G_TORCH: return '#'; - case G_CRYSTAL: return '#'; - case G_PORTCULLIS: return '#'; - case G_BARRICADE: return '#'; - case G_STATUE: return U_ESZETT; - case G_CRACKED_STATUE: return U_ESZETT; - case G_CLOSED_CAGE: return '#'; - case G_OPEN_CAGE: return '|'; - case G_PEDESTAL: return '|'; - case G_CLOSED_COFFIN: return '-'; - case G_OPEN_COFFIN: return '-'; - case G_MAGIC_GLYPH: return U_FOUR_DOTS; - case G_BRIDGE: return '='; - case G_BONES: return ','; - case G_ELECTRIC_CRYSTAL: return U_CURRENCY; - case G_ASHES: return '\''; - case G_BEDROLL: return '='; - case G_BLOODWORT_POD: return '*'; - case G_VINE: return ':'; - case G_NET: return ':'; - case G_LICHEN: return '"'; - case G_PIPES: return '+'; - case G_SAC_ALTAR: return '|'; - case G_ORB_ALTAR: return '|'; + case G_FOOD: + return ';'; + case G_UP_STAIRS: + return '<'; + case G_VENT: + return '='; + case G_DOWN_STAIRS: + return '>'; + case G_PLAYER: + return '@'; + case G_BOG_MONSTER: + return 'B'; + case G_CENTAUR: + return 'C'; + case G_DRAGON: + return 'D'; + case G_FLAMEDANCER: + return 'F'; + case G_GOLEM: + return 'G'; + case G_TENTACLE_HORROR: + return 'H'; + case G_IFRIT: + return 'I'; + case G_JELLY: + return 'J'; + case G_KRAKEN: + return 'K'; + case G_LICH: + return 'L'; + case G_NAGA: + return 'N'; + case G_OGRE: + return 'O'; + case G_PHANTOM: + return 'P'; + case G_REVENANT: + return 'R'; + case G_SALAMANDER: + return 'S'; + case G_TROLL: + return 'T'; + case G_UNDERWORM: + return 'U'; + case G_VAMPIRE: + return 'V'; + case G_WRAITH: + return 'W'; + case G_ZOMBIE: + return 'Z'; + case G_ARMOR: + return '['; + case G_STAFF: + return '/'; + case G_WEB: + return ':'; + case G_MOUND: + return 'a'; + case G_BLOAT: + return 'b'; + case G_CENTIPEDE: + return 'c'; + case G_DAR_BLADEMASTER: + return 'd'; + case G_EEL: + return 'e'; + case G_FURY: + return 'f'; + case G_GOBLIN: + return 'g'; + case G_IMP: + return 'i'; + case G_JACKAL: + return 'j'; + case G_KOBOLD: + return 'k'; + case G_MONKEY: + return 'm'; + case G_PIXIE: + return 'p'; + case G_RAT: + return 'r'; + case G_SPIDER: + return 's'; + case G_TOAD: + return 't'; + case G_BAT: + return 'v'; + case G_WISP: + return 'w'; + case G_PHOENIX: + return 'P'; + case G_ALTAR: + return '|'; + case G_LIQUID: + return '~'; + case G_FLOOR: + return U_MIDDLE_DOT; + case G_CHASM: + return U_FOUR_DOTS; + case G_TRAP: + return U_DIAMOND; + case G_FIRE: + return U_FLIPPED_V; + case G_FOLIAGE: + return U_ARIES; + case G_AMULET: + return U_ANKH; + case G_SCROLL: + return U_MUSIC_NOTE; + case G_RING: + return U_CIRCLE; + case G_WEAPON: + return U_UP_ARROW; + case G_GEM: + return U_FILLED_CIRCLE; + case G_TOTEM: + return U_NEUTER; + case G_GOOD_MAGIC: + return U_FILLED_CIRCLE_BARS; + case G_BAD_MAGIC: + return U_CIRCLE_BARS; + case G_DOORWAY: + return U_OMEGA; + case G_CHARM: + return U_LIGHTNING_BOLT; + case G_WALL_TOP: + return '#'; + case G_DAR_PRIESTESS: + return 'd'; + case G_DAR_BATTLEMAGE: + return 'd'; + case G_GOBLIN_MAGIC: + return 'g'; + case G_GOBLIN_CHIEFTAN: + return 'g'; + case G_OGRE_MAGIC: + return 'O'; + case G_GUARDIAN: + return U_ESZETT; + case G_WINGED_GUARDIAN: + return U_ESZETT; + case G_EGG: + return U_FILLED_CIRCLE; + case G_WARDEN: + return 'Y'; + case G_DEWAR: + return '&'; + case G_ANCIENT_SPIRIT: + return 'M'; + case G_LEVER: + return '/'; + case G_LEVER_PULLED: + return '\\'; + case G_BLOODWORT_STALK: + return U_ARIES; + case G_FLOOR_ALT: + return U_MIDDLE_DOT; + case G_UNICORN: + return U_U_ACUTE; + case G_TURRET: + return U_FILLED_CIRCLE; + case G_WAND: + return '~'; + case G_GRANITE: + return '#'; + case G_CARPET: + return U_MIDDLE_DOT; + case G_CLOSED_IRON_DOOR: + return '+'; + case G_OPEN_IRON_DOOR: + return '\''; + case G_TORCH: + return '#'; + case G_CRYSTAL: + return '#'; + case G_PORTCULLIS: + return '#'; + case G_BARRICADE: + return '#'; + case G_STATUE: + return U_ESZETT; + case G_CRACKED_STATUE: + return U_ESZETT; + case G_CLOSED_CAGE: + return '#'; + case G_OPEN_CAGE: + return '|'; + case G_PEDESTAL: + return '|'; + case G_CLOSED_COFFIN: + return '-'; + case G_OPEN_COFFIN: + return '-'; + case G_MAGIC_GLYPH: + return U_FOUR_DOTS; + case G_BRIDGE: + return '='; + case G_BONES: + return ','; + case G_ELECTRIC_CRYSTAL: + return U_CURRENCY; + case G_ASHES: + return '\''; + case G_BEDROLL: + return '='; + case G_BLOODWORT_POD: + return '*'; + case G_VINE: + return ':'; + case G_NET: + return ':'; + case G_LICHEN: + return '"'; + case G_PIPES: + return '+'; + case G_SAC_ALTAR: + return '|'; + case G_ORB_ALTAR: + return '|'; default: brogueAssert(false); @@ -192,26 +314,76 @@ Tells if a glyph represents part of the environment (true) or an item or creatur boolean isEnvironmentGlyph(enum displayGlyph glyph) { switch (glyph) { // items - case G_AMULET: case G_ARMOR: case G_BEDROLL: case G_CHARM: - case G_DEWAR: case G_EGG: case G_FOOD: case G_GEM: case G_BLOODWORT_POD: - case G_GOLD: case G_KEY: case G_POTION: case G_RING: - case G_SCROLL: case G_STAFF: case G_WAND: case G_WEAPON: + case G_AMULET: + case G_ARMOR: + case G_BEDROLL: + case G_CHARM: + case G_DEWAR: + case G_EGG: + case G_FOOD: + case G_GEM: + case G_BLOODWORT_POD: + case G_GOLD: + case G_KEY: + case G_POTION: + case G_RING: + case G_SCROLL: + case G_STAFF: + case G_WAND: + case G_WEAPON: return false; // creatures - case G_ANCIENT_SPIRIT: case G_BAT: case G_BLOAT: case G_BOG_MONSTER: - case G_CENTAUR: case G_CENTIPEDE: case G_DAR_BATTLEMAGE: case G_DAR_BLADEMASTER: - case G_DAR_PRIESTESS: case G_DEMON: case G_DRAGON: case G_EEL: - case G_FLAMEDANCER: case G_FURY: case G_GOBLIN: case G_GOBLIN_CHIEFTAN: - case G_GOBLIN_MAGIC: case G_GOLEM: case G_GUARDIAN: case G_IFRIT: - case G_IMP: case G_JACKAL: case G_JELLY: case G_KOBOLD: - case G_KRAKEN: case G_LICH: case G_MONKEY: case G_MOUND: - case G_NAGA: case G_OGRE: case G_OGRE_MAGIC: case G_PHANTOM: - case G_PHOENIX: case G_PIXIE: case G_PLAYER: case G_RAT: - case G_REVENANT: case G_SALAMANDER: case G_SPIDER: case G_TENTACLE_HORROR: - case G_TOAD: case G_TROLL: case G_UNDERWORM: case G_UNICORN: - case G_VAMPIRE: case G_WARDEN: case G_WINGED_GUARDIAN: case G_WISP: - case G_WRAITH: case G_ZOMBIE: + case G_ANCIENT_SPIRIT: + case G_BAT: + case G_BLOAT: + case G_BOG_MONSTER: + case G_CENTAUR: + case G_CENTIPEDE: + case G_DAR_BATTLEMAGE: + case G_DAR_BLADEMASTER: + case G_DAR_PRIESTESS: + case G_DEMON: + case G_DRAGON: + case G_EEL: + case G_FLAMEDANCER: + case G_FURY: + case G_GOBLIN: + case G_GOBLIN_CHIEFTAN: + case G_GOBLIN_MAGIC: + case G_GOLEM: + case G_GUARDIAN: + case G_IFRIT: + case G_IMP: + case G_JACKAL: + case G_JELLY: + case G_KOBOLD: + case G_KRAKEN: + case G_LICH: + case G_MONKEY: + case G_MOUND: + case G_NAGA: + case G_OGRE: + case G_OGRE_MAGIC: + case G_PHANTOM: + case G_PHOENIX: + case G_PIXIE: + case G_PLAYER: + case G_RAT: + case G_REVENANT: + case G_SALAMANDER: + case G_SPIDER: + case G_TENTACLE_HORROR: + case G_TOAD: + case G_TROLL: + case G_UNDERWORM: + case G_UNICORN: + case G_VAMPIRE: + case G_WARDEN: + case G_WINGED_GUARDIAN: + case G_WISP: + case G_WRAITH: + case G_ZOMBIE: return false; // everything else is considered part of the environment @@ -220,31 +392,18 @@ boolean isEnvironmentGlyph(enum displayGlyph glyph) { } } -void plotChar(enum displayGlyph inputChar, - short xLoc, short yLoc, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue) { +void plotChar(enum displayGlyph inputChar, short xLoc, short yLoc, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue) { currentConsole.plotChar(inputChar, xLoc, yLoc, foreRed, foreGreen, foreBlue, backRed, backGreen, backBlue); } -void pausingTimerStartsNow() { +void pausingTimerStartsNow() {} -} +boolean shiftKeyIsDown() { return currentConsole.modifierHeld(0); } +boolean controlKeyIsDown() { return currentConsole.modifierHeld(1); } -boolean shiftKeyIsDown() { - return currentConsole.modifierHeld(0); -} -boolean controlKeyIsDown() { - return currentConsole.modifierHeld(1); -} +void nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance) { currentConsole.nextKeyOrMouseEvent(returnEvent, textInput, colorsDance); } -void nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance) { - currentConsole.nextKeyOrMouseEvent(returnEvent, textInput, colorsDance); -} - -boolean pauseForMilliseconds(short milliseconds) { - return currentConsole.pauseForMilliseconds(milliseconds); -} +boolean pauseForMilliseconds(short milliseconds) { return currentConsole.pauseForMilliseconds(milliseconds); } void notifyEvent(short eventId, int data1, int data2, const char *str1, const char *str2) { if (currentConsole.notifyEvent) { @@ -277,8 +436,8 @@ void initScores() { setHighScoresFilename(highScoresFilename, BROGUE_FILENAME_MAX); scoresFile = fopen(highScoresFilename, "w"); - for (i=0; i= highestUnsortedScore) { highestUnsortedLine = j; highestUnsortedScore = scoreBuffer[j].score; @@ -311,7 +470,7 @@ short sortScoreBuffer() { } // copy the sorted list back into scoreBuffer, remember the most recent entry - for (i=0; i mostRecentDate) { mostRecentDate = scoreBuffer[i].dateNumber; @@ -333,7 +492,7 @@ short loadScoreBuffer() { short i; FILE *scoresFile; time_t rawtime; - struct tm * timeinfo; + struct tm *timeinfo; char highScoresFilename[BROGUE_FILENAME_MAX]; setHighScoresFilename(highScoresFilename, BROGUE_FILENAME_MAX); @@ -345,7 +504,7 @@ short loadScoreBuffer() { scoresFile = fopen(highScoresFilename, "r"); } - for (i=0; i 0) { - printf("%d\t%s\t%s\n", (int) list[i].score, list[i].date, list[i].description); + printf("%d\t%s\t%s\n", (int)list[i].score, list[i].date, list[i].description); } } } @@ -439,10 +599,10 @@ short getHighScoresList(rogueHighScoresEntry returnList[HIGH_SCORES_COUNT]) { mostRecentLineNumber = loadScoreBuffer(); - for (i=0; ifiles[list->nfiles].path = ((char *) NULL) + list->nextname; // don't look at them until they are transferred out - list->files[list->nfiles].date = (struct tm) {0}; // associate a dummy date (1899-12-31) to avoid random data, it will be correctly populated when using listFiles() + list->files[list->nfiles].path = ((char *)NULL) + list->nextname; // don't look at them until they are transferred out + list->files[list->nfiles].date = (struct tm){0}; // associate a dummy date (1899-12-31) to avoid random data, it + // will be correctly populated when using listFiles() strncpy(list->names + list->nextname, name, len + 1); @@ -537,14 +698,15 @@ fileEntry *addfile(struct filelist *list, const char *name) { } void freeFilelist(struct filelist *list) { - //if (list->names != NULL) free(list->names); - //if (list->files != NULL) free(list->files); + // if (list->names != NULL) free(list->names); + // if (list->files != NULL) free(list->files); free(list); } fileEntry *commitFilelist(struct filelist *list, char **namebuffer) { int i; - /*fileEntry *files = malloc(list->nfiles * sizeof(fileEntry) + list->nextname); // enough space for all the names and all the files + /*fileEntry *files = malloc(list->nfiles * sizeof(fileEntry) + list->nextname); // enough space for all the names + and all the files if (files != NULL) { char *names = (char *) (files + list->nfiles); @@ -557,8 +719,8 @@ fileEntry *commitFilelist(struct filelist *list, char **namebuffer) { memcpy(names, list->names, list->nextname); } */ - for (i=0; i < list->nfiles; i++) { - list->files[i].path = list->names + (list->files[i].path - (char *) NULL); + for (i = 0; i < list->nfiles; i++) { + list->files[i].path = list->names + (list->files[i].path - (char *)NULL); } *namebuffer = list->names; @@ -569,7 +731,7 @@ fileEntry *listFiles(short *fileCount, char **namebuffer) { struct filelist *list = newFilelist(); // windows: FindFirstFile/FindNextFile - DIR *dp= opendir ("./"); + DIR *dp = opendir("./"); if (dp != NULL) { struct dirent *ep; @@ -588,9 +750,8 @@ fileEntry *listFiles(short *fileCount, char **namebuffer) { } } - closedir (dp); - } - else { + closedir(dp); + } else { *fileCount = 0; return NULL; } @@ -598,7 +759,7 @@ fileEntry *listFiles(short *fileCount, char **namebuffer) { fileEntry *files = commitFilelist(list, namebuffer); if (files != NULL) { - *fileCount = (short) list->nfiles; + *fileCount = (short)list->nfiles; } else { *fileCount = 0; } @@ -618,4 +779,3 @@ boolean isApplicationActive(void) { // FIXME: finish return true; } - diff --git a/src/platform/sdl2-platform.c b/src/platform/sdl2-platform.c index e8cbf73e..b2bf5c4a 100644 --- a/src/platform/sdl2-platform.c +++ b/src/platform/sdl2-platform.c @@ -7,8 +7,8 @@ #include "platform.h" #include "tiles.h" -#define PAUSE_BETWEEN_EVENT_POLLING 36L//17 -#define MAX_REMAPS 128 +#define PAUSE_BETWEEN_EVENT_POLLING 36L // 17 +#define MAX_REMAPS 128 struct keypair { char from; @@ -21,19 +21,16 @@ static enum graphicsModes showGraphics = TEXT_GRAPHICS; static rogueEvent lastEvent; - static void sdlfatal(char *file, int line) { fprintf(stderr, "Fatal SDL error (%s:%d): %s\n", file, line, SDL_GetError()); exit(EXIT_STATUS_FAILURE_PLATFORM_ERROR); } - static void imgfatal(char *file, int line) { fprintf(stderr, "Fatal SDL_image error (%s:%d): %s\n", file, line, IMG_GetError()); exit(EXIT_STATUS_FAILURE_PLATFORM_ERROR); } - /* If the key is to be processed, returns true and updates event. False otherwise. This function only listens for keypresses which do not produce @@ -122,22 +119,18 @@ static boolean eventFromKey(rogueEvent *event, SDL_Keycode key) { return false; } - static boolean _modifierHeld(int mod) { SDL_Keymod km = SDL_GetModState(); - return mod == 0 && (km & (KMOD_LSHIFT | KMOD_RSHIFT)) - || mod == 1 && (km & (KMOD_LCTRL | KMOD_RCTRL)); + return mod == 0 && (km & (KMOD_LSHIFT | KMOD_RSHIFT)) || mod == 1 && (km & (KMOD_LCTRL | KMOD_RCTRL)); } - static char applyRemaps(char c) { - for (size_t i=0; i < nremaps; i++) { + for (size_t i = 0; i < nremaps; i++) { if (remapping[i].from == c) return remapping[i].to; } return c; } - /* If an event is available, returns true and updates returnEvent. Otherwise it returns false and an error event. This function also processes @@ -153,7 +146,6 @@ static boolean pollBrogueEvent(rogueEvent *returnEvent, boolean textInput) { SDL_Event event; boolean ret = false; - // ~ for (int i=0; i < 100 && SDL_PollEvent(&event); i++) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { @@ -167,16 +159,15 @@ static boolean pollBrogueEvent(rogueEvent *returnEvent, boolean textInput) { SDL_Keycode key = event.key.keysym.sym; if (key == SDLK_PAGEUP) { - resizeWindow(max(windowWidth * 11/10, windowWidth + 1), max(windowHeight * 11/10, windowHeight + 1)); + resizeWindow(max(windowWidth * 11 / 10, windowWidth + 1), max(windowHeight * 11 / 10, windowHeight + 1)); continue; } else if (key == SDLK_PAGEDOWN) { fullScreen = false; - resizeWindow(max(windowWidth * 10/11, 1), max(windowHeight * 10/11, 1)); + resizeWindow(max(windowWidth * 10 / 11, 1), max(windowHeight * 10 / 11, 1)); continue; - } else if (key == SDLK_F11 || key == SDLK_F12 - || key == SDLK_RETURN && (SDL_GetModState() & KMOD_ALT)) { + } else if (key == SDLK_F11 || key == SDLK_F12 || key == SDLK_RETURN && (SDL_GetModState() & KMOD_ALT)) { fullScreen = !fullScreen; - resizeWindow(-1, -1); // Reset to starting resolution + resizeWindow(-1, -1); // Reset to starting resolution continue; } @@ -197,10 +188,10 @@ static boolean pollBrogueEvent(rogueEvent *returnEvent, boolean textInput) { if (!textInput) { c = applyRemaps(c); if (c == '=' || c == '+') { - resizeWindow(max(windowWidth * 11/10, windowWidth + 1), max(windowHeight * 11/10, windowHeight + 1)); + resizeWindow(max(windowWidth * 11 / 10, windowWidth + 1), max(windowHeight * 11 / 10, windowHeight + 1)); } else if (c == '-') { fullScreen = false; - resizeWindow(max(windowWidth * 10/11, 1), max(windowHeight * 10/11, 1)); + resizeWindow(max(windowWidth * 10 / 11, 1), max(windowHeight * 10 / 11, 1)); } } @@ -226,8 +217,7 @@ static boolean pollBrogueEvent(rogueEvent *returnEvent, boolean textInput) { } else if (event.type == SDL_MOUSEMOTION) { // We don't want to return on a mouse motion event, because only the last // in the queue is important. That's why we just set ret=true - int xcell = event.motion.x * COLS / windowWidth, - ycell = event.motion.y * ROWS / windowHeight; + int xcell = event.motion.x * COLS / windowWidth, ycell = event.motion.y * ROWS / windowHeight; if (xcell != mx || ycell != my) { returnEvent->eventType = MOUSE_ENTERED_CELL; returnEvent->param1 = xcell; @@ -242,13 +232,12 @@ static boolean pollBrogueEvent(rogueEvent *returnEvent, boolean textInput) { return ret; } - static void _gameLoop() { #ifdef SDL_PATHS char *path = SDL_GetBasePath(); if (path) { fprintf(stderr, "Base path: %s\n", path); - path[strlen(path) - 1] = '\0'; // remove trailing separator + path[strlen(path) - 1] = '\0'; // remove trailing separator strcpy(dataDirectory, path); } else { fprintf(stderr, "Failed to find the path to the application\n"); @@ -282,22 +271,19 @@ static void _gameLoop() { exit(statusCode); } - static boolean _pauseForMilliseconds(short ms) { updateScreen(); SDL_Delay(ms); - if (lastEvent.eventType != EVENT_ERROR - && lastEvent.eventType != MOUSE_ENTERED_CELL) { + if (lastEvent.eventType != EVENT_ERROR && lastEvent.eventType != MOUSE_ENTERED_CELL) { return true; // SDL already gave us an interrupting event to process } - return pollBrogueEvent(&lastEvent, false) // ask SDL for a new event if one is available - && lastEvent.eventType != EVENT_ERROR // and check if it is interrupting - && lastEvent.eventType != MOUSE_ENTERED_CELL; + return pollBrogueEvent(&lastEvent, false) // ask SDL for a new event if one is available + && lastEvent.eventType != EVENT_ERROR // and check if it is interrupting + && lastEvent.eventType != MOUSE_ENTERED_CELL; } - static void _nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance) { long tstart, dt; @@ -328,7 +314,6 @@ static void _nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boo } } - /* Returns the index of the sprite representing the given glyph. Sprites <256 are from the text font sheet, 256+ are from the tiles sheet. @@ -348,27 +333,48 @@ static int fontIndex(enum displayGlyph glyph) { } else { unsigned int code = glyphToUnicode(glyph); switch (code) { - case U_MIDDLE_DOT: return 0x80; - case U_FOUR_DOTS: return 0x81; - case U_DIAMOND: return 0x82; - case U_FLIPPED_V: return 0x83; - case U_ARIES: return 0x84; - case U_ESZETT: return 0xdf; - case U_ANKH: return 0x85; - case U_MUSIC_NOTE: return 0x86; - case U_CIRCLE: return 0x87; - case U_LIGHTNING_BOLT: return 0x99; - case U_FILLED_CIRCLE: return 0x89; - case U_NEUTER: return 0x8a; - case U_U_ACUTE: return 0xda; - case U_CURRENCY: return 0xa4; - case U_UP_ARROW: return 0x90; - case U_DOWN_ARROW: return 0x91; - case U_LEFT_ARROW: return 0x92; - case U_RIGHT_ARROW: return 0x93; - case U_OMEGA: return 0x96; - case U_CIRCLE_BARS: return 0x8c; - case U_FILLED_CIRCLE_BARS: return 0x8d; + case U_MIDDLE_DOT: + return 0x80; + case U_FOUR_DOTS: + return 0x81; + case U_DIAMOND: + return 0x82; + case U_FLIPPED_V: + return 0x83; + case U_ARIES: + return 0x84; + case U_ESZETT: + return 0xdf; + case U_ANKH: + return 0x85; + case U_MUSIC_NOTE: + return 0x86; + case U_CIRCLE: + return 0x87; + case U_LIGHTNING_BOLT: + return 0x99; + case U_FILLED_CIRCLE: + return 0x89; + case U_NEUTER: + return 0x8a; + case U_U_ACUTE: + return 0xda; + case U_CURRENCY: + return 0xa4; + case U_UP_ARROW: + return 0x90; + case U_DOWN_ARROW: + return 0x91; + case U_LEFT_ARROW: + return 0x92; + case U_RIGHT_ARROW: + return 0x93; + case U_OMEGA: + return 0x96; + case U_CIRCLE_BARS: + return 0x8c; + case U_FILLED_CIRCLE_BARS: + return 0x8d; default: brogueAssert(code < 256); @@ -377,19 +383,10 @@ static int fontIndex(enum displayGlyph glyph) { } } - -static void _plotChar( - enum displayGlyph inputChar, - short x, short y, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue -) { - updateTile(y, x, fontIndex(inputChar), - foreRed, foreGreen, foreBlue, - backRed, backGreen, backBlue); +static void _plotChar(enum displayGlyph inputChar, short x, short y, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue) { + updateTile(y, x, fontIndex(inputChar), foreRed, foreGreen, foreBlue, backRed, backGreen, backBlue); } - static void _remap(const char *from, const char *to) { if (nremaps < MAX_REMAPS) { remapping[nremaps].from = from[0]; @@ -398,7 +395,6 @@ static void _remap(const char *from, const char *to) { } } - /* * Take screenshot in current working directory (ScreenshotN.png) */ @@ -418,7 +414,6 @@ static boolean _takeScreenshot() { return true; } - static enum graphicsModes _setGraphicsMode(enum graphicsModes mode) { showGraphics = mode; refreshScreen(); @@ -426,15 +421,4 @@ static enum graphicsModes _setGraphicsMode(enum graphicsModes mode) { return mode; } - -struct brogueConsole sdlConsole = { - _gameLoop, - _pauseForMilliseconds, - _nextKeyOrMouseEvent, - _plotChar, - _remap, - _modifierHeld, - NULL, - _takeScreenshot, - _setGraphicsMode -}; +struct brogueConsole sdlConsole = {_gameLoop, _pauseForMilliseconds, _nextKeyOrMouseEvent, _plotChar, _remap, _modifierHeld, NULL, _takeScreenshot, _setGraphicsMode}; diff --git a/src/platform/term.c b/src/platform/term.c index 9d209c44..430537b8 100644 --- a/src/platform/term.c +++ b/src/platform/term.c @@ -6,24 +6,21 @@ #include "Rogue.h" #include - // As a rule, everything in term.c is the result of gradual evolutionary // change. It's messy. -#define COLORING(fg,bg) (((fg) & 0x0f) | (((bg) & 0x07) << 4)) -#define COLOR_FG(color,fg) (((fg) & 0x0f) + ((color) & 0x70)) -#define COLOR_BG(color,bg) (((color) & 0x0f) + (((bg) & 0x07) << 4)) +#define COLORING(fg, bg) (((fg)&0x0f) | (((bg)&0x07) << 4)) +#define COLOR_FG(color, fg) (((fg)&0x0f) + ((color)&0x70)) +#define COLOR_BG(color, bg) (((color)&0x0f) + (((bg)&0x07) << 4)) #define COLOR_INDEX(color) (1 + ((color)&0x07) + (((color) >> 1) & 0x38)) #define COLOR_ATTR(color) (COLOR_PAIR(COLOR_INDEX(color)) | (((color)&0x08) ? A_BOLD : 0)) +static struct { int curses, color; } videomode = {0, 0}; -static struct { int curses, color; } videomode = { 0, 0 }; - -static struct { int width, height; } minsize = { 80, 24 }; +static struct { int width, height; } minsize = {80, 24}; static void init_coersion(); - // 256 color mode stuff static void initialize_prs(); @@ -36,7 +33,6 @@ struct { int count, next; } prs[256]; - typedef struct { int ch, pair, shuffle; intcolor fore, back; @@ -44,31 +40,20 @@ typedef struct { pairmode_cell *cell_buffer; -enum { - coerce_16, - coerce_256, - truecolor -} colormode; +enum { coerce_16, coerce_256, truecolor } colormode; int is_xterm; - // -static void preparecolor ( ) { +static void preparecolor() { // sixteen color mode colors (we use these in 256-color mode, too) - static int pairParts[8] = { - COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, - COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE - }; + static int pairParts[8] = {COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE}; int fg, bg; - for (bg=0; bg<8; bg++) { - for (fg=0; fg<8; fg++) { - init_pair( - COLOR_INDEX(COLORING(fg, bg)), - pairParts[fg], pairParts[bg] - ); + for (bg = 0; bg < 8; bg++) { + for (fg = 0; fg < 8; fg++) { + init_pair(COLOR_INDEX(COLORING(fg, bg)), pairParts[fg], pairParts[bg]); } } @@ -84,19 +69,19 @@ static void preparecolor ( ) { static void term_title(const char *title) { if (is_xterm) { - printf ("\033]2;%s\007", title); // ESC ]0; title BEL + printf("\033]2;%s\007", title); // ESC ]0; title BEL } } static void term_title_pop() { if (is_xterm) { term_title("Terminal"); - printf ("\033[22;2t"); + printf("\033[22;2t"); } } static void term_title_push() { if (is_xterm) { - printf ("\033[23;2t"); + printf("\033[23;2t"); } } @@ -104,13 +89,13 @@ static void term_set_size(int h, int w) { // works in gnome-terminal, but not xterm; causes trouble for maximized windows if (is_xterm) { // first, try resizing the height, in case only that is supported - printf ("\033[%dt", (h > 24 ? h : 24)); + printf("\033[%dt", (h > 24 ? h : 24)); // then try resizing both, in case we can - printf ("\033[8;%d;%dt", h, w); + printf("\033[8;%d;%dt", h, w); // then refresh so ncurses knows about it - refresh( ); + refresh(); } } @@ -118,40 +103,40 @@ static void term_show_scrollbar(int show) { // works in xterm, but not gnome-terminal if (is_xterm) { if (show) { - printf ("\033[?30h"); + printf("\033[?30h"); } else { - printf ("\033[?30l"); + printf("\033[?30l"); } } } -static int curses_init( ) { +static int curses_init() { if (videomode.curses) return 0; // isterm? - initscr( ); - if (!has_colors( )) { - endwin( ); - fprintf (stderr, "Your terminal has no color support.\n"); + initscr(); + if (!has_colors()) { + endwin(); + fprintf(stderr, "Your terminal has no color support.\n"); return 1; } - start_color( ); - clear( ); - curs_set( 0 ); - refresh( ); + start_color(); + clear(); + curs_set(0); + refresh(); leaveok(stdscr, TRUE); - preparecolor( ); - raw( ); - noecho( ); - nonl( ); + preparecolor(); + raw(); + noecho(); + nonl(); nodelay(stdscr, TRUE); meta(stdscr, TRUE); keypad(stdscr, TRUE); mousemask(BUTTON1_PRESSED | BUTTON1_RELEASED | REPORT_MOUSE_POSITION | BUTTON_SHIFT | BUTTON_CTRL, NULL); - mouseinterval(0); //do no click processing, thank you + mouseinterval(0); // do no click processing, thank you videomode.curses = 1; @@ -160,7 +145,6 @@ static int curses_init( ) { return 1; } - static int term_start() { char *term = getenv("TERM"); is_xterm = (strncmp(term, "xterm", 5) == 0) || (strncmp(term, "gnome", 5) == 0) || (strncmp(term, "st", 2) == 0); @@ -196,25 +180,9 @@ typedef struct Lab { #define HALFBRIGHT 0.5 #define BRIGHT 0.9 -fcolor palette[16] = { - {DARK, DARK, DARK}, - {MID, DARK, DARK}, - {DARK, MID, DARK}, - {MID, .8 * MID, DIM}, - {DARK, DARK, MID}, - {MID + DIM, DARK, MID}, - {DARK, MID, MID}, - {HALFBRIGHT, HALFBRIGHT, HALFBRIGHT}, - - {MID, MID, MID}, - {BRIGHT, DARK, DARK}, - {DARK, BRIGHT, DARK}, - {BRIGHT, BRIGHT, DARK}, - {HALFBRIGHT, MID, BRIGHT}, - {BRIGHT, HALFBRIGHT, BRIGHT}, - {DARK, BRIGHT, BRIGHT}, - {BRIGHT, BRIGHT, BRIGHT} -}; +fcolor palette[16] = {{DARK, DARK, DARK}, {MID, DARK, DARK}, {DARK, MID, DARK}, {MID, .8 * MID, DIM}, {DARK, DARK, MID}, {MID + DIM, DARK, MID}, {DARK, MID, MID}, {HALFBRIGHT, HALFBRIGHT, HALFBRIGHT}, + + {MID, MID, MID}, {BRIGHT, DARK, DARK}, {DARK, BRIGHT, DARK}, {BRIGHT, BRIGHT, DARK}, {HALFBRIGHT, MID, BRIGHT}, {BRIGHT, HALFBRIGHT, BRIGHT}, {DARK, BRIGHT, BRIGHT}, {BRIGHT, BRIGHT, BRIGHT}}; CIE ciePalette[16]; Lab labPalette[16]; @@ -245,12 +213,10 @@ static CIE toCIE(fcolor c) { return cie; } -static float Labf(float t) { - return t > ((6.0/29.0) * (6.0/29.0) * (6.0/29.0)) ? pow(t, 1.0/3.0) : ((1.0/3.0) * (29.0 / 6.0) * (29.0 / 6.0)) * t + (4.0 / 29.0); -} +static float Labf(float t) { return t > ((6.0 / 29.0) * (6.0 / 29.0) * (6.0 / 29.0)) ? pow(t, 1.0 / 3.0) : ((1.0 / 3.0) * (29.0 / 6.0) * (29.0 / 6.0)) * t + (4.0 / 29.0); } static Lab toLab(CIE *c) { - CIE n = (CIE) {Labf(c->X / white.X), Labf(c->Y / white.Y), Labf(c->Z / white.Z)}; + CIE n = (CIE){Labf(c->X / white.X), Labf(c->Y / white.Y), Labf(c->Z / white.Z)}; Lab l; // http://en.wikipedia.org/wiki/L*a*b*#RGB_and_CMYK_conversions @@ -261,9 +227,7 @@ static Lab toLab(CIE *c) { return l; } -static float munsellSloanGodlove(float t) { - return sqrt(1.4742 * t - 0.004743 * t * t); -} +static float munsellSloanGodlove(float t) { return sqrt(1.4742 * t - 0.004743 * t * t); } static CIE adams(CIE *v) { CIE c; @@ -283,7 +247,7 @@ static float CIE76(Lab *L1, Lab *L2) { } static void init_coersion() { - fcolor sRGB_white = (fcolor) {1, 1, 1}; + fcolor sRGB_white = (fcolor){1, 1, 1}; white = toCIE(sRGB_white); int i; @@ -300,7 +264,7 @@ static void init_coersion() { cell_buffer = 0; } -static int best (fcolor *fg, fcolor *bg) { +static int best(fcolor *fg, fcolor *bg) { // analyze fg & bg for their contrast CIE cieFg = toCIE(*fg); CIE cieBg = toCIE(*bg); @@ -309,7 +273,7 @@ static int best (fcolor *fg, fcolor *bg) { // CIE adamsFg = adams(&cieFg); // CIE adamsBg = adams(&cieBg); - float JND = 2.3; // just-noticeable-difference + float JND = 2.3; // just-noticeable-difference int areTheSame = CIE76(&labFg, &labBg) <= 2.0 * JND; // a little extra fudge float big = 100000000; @@ -324,10 +288,13 @@ static int best (fcolor *fg, fcolor *bg) { if (s < bg2_score) { if (s < bg1_score) { - bg2 = bg1; bg1 = i; - bg2_score = bg1_score; bg1_score = s; + bg2 = bg1; + bg1 = i; + bg2_score = bg1_score; + bg1_score = s; } else { - bg2 = i; bg2_score = s; + bg2 = i; + bg2_score = s; } } } @@ -341,16 +308,19 @@ static int best (fcolor *fg, fcolor *bg) { if (s < fg2_score) { if (s < fg1_score) { - fg2 = fg1; fg1 = i; - fg2_score = fg1_score; fg1_score = s; + fg2 = fg1; + fg1 = i; + fg2_score = fg1_score; + fg1_score = s; } else { - fg2 = i; fg2_score = s; + fg2 = i; + fg2_score = s; } } } if (fg1 != bg1) { - return COLORING (fg1, bg1); + return COLORING(fg1, bg1); } else { if (fg1_score + bg2_score < fg2_score + bg1_score) { return COLORING(fg1, bg2); @@ -360,9 +330,6 @@ static int best (fcolor *fg, fcolor *bg) { } } - - - static void initialize_prs() { int i; for (i = 16; i < 255; i++) { @@ -373,20 +340,21 @@ static void initialize_prs() { prs[255].next = 0; } -static void coerce_colorcube (fcolor *f, intcolor *c) { +static void coerce_colorcube(fcolor *f, intcolor *c) { // 0-15 are the standard ANSI colors // 16-231 are a 6x6x6 RGB color cube given by ((36 * r) + (6 * g) + b + 16) with r,g,b in [0..5] // 232-255 are a greyscale ramp without black and white. float sat = 0.2, bright = 0.6, contrast = 6.3; - float rf = bright + f->r * contrast, - gf = bright + f->g * contrast, - bf = bright + f->b * contrast; + float rf = bright + f->r * contrast, gf = bright + f->g * contrast, bf = bright + f->b * contrast; - if (rf < gf && rf < bf) rf -= sat * ((gf < bf ? bf : gf) - rf); - else if (gf < bf && gf < rf) gf -= sat * ((rf < bf ? bf : rf) - gf); - else if (bf < gf && bf < rf) bf -= sat * ((gf < rf ? rf : gf) - bf); + if (rf < gf && rf < bf) + rf -= sat * ((gf < bf ? bf : gf) - rf); + else if (gf < bf && gf < rf) + gf -= sat * ((rf < bf ? bf : rf) - gf); + else if (bf < gf && bf < rf) + bf -= sat * ((gf < rf ? rf : gf) - bf); int r = rf, g = gf, b = bf; r = r < 0 ? 0 : r > 5 ? 5 : r; @@ -399,14 +367,9 @@ static void coerce_colorcube (fcolor *f, intcolor *c) { c->idx = ((36 * r) + (6 * g) + b + 16); } -static int intcolor_distance (intcolor *a, intcolor *b) { - return - (a->r - b->r) * (a->r - b->r) - + (a->g - b->g) * (a->g - b->g) - + (a->b - b->b) * (a->b - b->b); -} +static int intcolor_distance(intcolor *a, intcolor *b) { return (a->r - b->r) * (a->r - b->r) + (a->g - b->g) * (a->g - b->g) + (a->b - b->b) * (a->b - b->b); } -static int coerce_prs (intcolor *fg, intcolor *bg) { +static int coerce_prs(intcolor *fg, intcolor *bg) { // search for an exact match in the list int pair; pair = prs[1].next; @@ -467,7 +430,6 @@ static void buffer_plot(int ch, int x, int y, fcolor *fg, fcolor *bg) { // pair = cube_bg.idx; // cube_fg = cube_bg; - // init_pair(pair, cube_fg.idx, cube_bg.idx); // return pair; @@ -479,28 +441,26 @@ static void buffer_plot(int ch, int x, int y, fcolor *fg, fcolor *bg) { coerce_colorcube(bg, &cube_bg); if (cube_fg.idx == cube_bg.idx) { // verify that the colors are really the same; otherwise, we'd better force the output apart - int naive_distance = - (fg->r - bg->r) * (fg->r - bg->r) - + (fg->g - bg->g) * (fg->g - bg->g) - + (fg->b - bg->b) * (fg->b - bg->b); + int naive_distance = (fg->r - bg->r) * (fg->r - bg->r) + (fg->g - bg->g) * (fg->g - bg->g) + (fg->b - bg->b) * (fg->b - bg->b); if (naive_distance > 3) { // very arbitrary cutoff, and an arbitrary fix, very lazy - if (cube_bg.r > 0) {cube_bg.r -= 1; cube_bg.idx -= 1; } - if (cube_bg.g > 0) {cube_bg.g -= 1; cube_bg.idx -= 6; } - if (cube_bg.b > 0) {cube_bg.b -= 1; cube_bg.idx -= 36; } + if (cube_bg.r > 0) { + cube_bg.r -= 1; + cube_bg.idx -= 1; + } + if (cube_bg.g > 0) { + cube_bg.g -= 1; + cube_bg.idx -= 6; + } + if (cube_bg.b > 0) { + cube_bg.b -= 1; + cube_bg.idx -= 36; + } } } } else { - cube_fg = (intcolor){ - .r = round(fg->r * 255), - .g = round(fg->g * 255), - .b = round(fg->b * 255) - }; - cube_bg = (intcolor){ - .r = round(bg->r * 255), - .g = round(bg->g * 255), - .b = round(bg->b * 255) - }; + cube_fg = (intcolor){.r = round(fg->r * 255), .g = round(fg->g * 255), .b = round(fg->b * 255)}; + cube_bg = (intcolor){.r = round(bg->r * 255), .g = round(bg->g * 255), .b = round(bg->b * 255)}; } int cell = x + y * minsize.width; @@ -576,7 +536,7 @@ static void buffer_render_24bit() { // move cursor if necessary if (cx != x || cy != y) { cx = x, cy = y; - printf("\033[%d;%df", cy+1, cx+1); + printf("\033[%d;%df", cy + 1, cx + 1); } // print the character @@ -636,9 +596,9 @@ static void term_refresh() { } } -static void ensure_size( ); +static void ensure_size(); -static int term_getkey( ) { +static int term_getkey() { Term.mouse.justPressed = 0; Term.mouse.justReleased = 0; Term.mouse.justMoved = 0; @@ -646,11 +606,11 @@ static int term_getkey( ) { while (1) { int got = getch(); if (got == KEY_RESIZE) { - ensure_size( ); + ensure_size(); fullRefresh = 1; } else if (got == KEY_MOUSE) { MEVENT mevent; - getmouse (&mevent); + getmouse(&mevent); Term.mouse.x = mevent.x; Term.mouse.y = mevent.y; Term.mouse.shift = (mevent.bstate & BUTTON_SHIFT) != 0; @@ -669,8 +629,10 @@ static int term_getkey( ) { return TERM_MOUSE; } else { if (got == KEY_ENTER) got = 13; // KEY_ENTER -> ^M for systems with odd values for KEY_ENTER - if (got == ERR) return TERM_NONE; - else return got; + if (got == ERR) + return TERM_NONE; + else + return got; } } } @@ -685,7 +647,7 @@ static int term_has_key() { } } -static void ensure_size( ) { +static void ensure_size() { int w = minsize.width, h = minsize.height; getmaxyx(stdscr, Term.height, Term.width); @@ -696,13 +658,13 @@ static void ensure_size( ) { erase(); attrset(COLOR_ATTR(7)); - mvprintw(1,0,"Brogue needs a terminal window that is at least [%d x %d]", w, h); + mvprintw(1, 0, "Brogue needs a terminal window that is at least [%d x %d]", w, h); attrset(COLOR_ATTR(15)); - mvprintw(2,0,"If your terminal can be resized, resize it now.\n"); + mvprintw(2, 0, "If your terminal can be resized, resize it now.\n"); attrset(COLOR_ATTR(7)); - mvprintw(3,0,"Press ctrl-c at any time to quit.\n"); + mvprintw(3, 0, "Press ctrl-c at any time to quit.\n"); printw("Width: %d/%d\n", Term.width, w); printw("Height: %d/%d\n", Term.height, h); @@ -729,7 +691,6 @@ static void term_resize(int w, int h) { // now make sure it worked, and ask the user to resize the terminal if it didn't ensure_size(); - // make a new cell buffer if (cell_buffer) free(cell_buffer); @@ -746,10 +707,7 @@ static void term_resize(int w, int h) { } } -static void term_wait(int ms) { - napms(ms); -} - +static void term_wait(int ms) { napms(ms); } struct { char *name; @@ -769,7 +727,7 @@ struct { {"SRESET", KEY_SRESET}, {"RESET", KEY_RESET}, {"DOWN", KEY_DOWN}, - {"UP", KEY_UP }, + {"UP", KEY_UP}, {"LEFT", KEY_LEFT}, {"RIGHT", KEY_RIGHT}, {"HOME", KEY_HOME}, @@ -818,13 +776,13 @@ struct { {"C1", KEY_C1}, {"C3", KEY_C3}, {"BTAB", KEY_BTAB}, - {"BEG", KEY_BEG }, + {"BEG", KEY_BEG}, {"CANCEL", KEY_CANCEL}, {"CLOSE", KEY_CLOSE}, {"COMMAND", KEY_COMMAND}, {"COPY", KEY_COPY}, {"CREATE", KEY_CREATE}, - {"END", KEY_END }, + {"END", KEY_END}, {"EXIT", KEY_EXIT}, {"FIND", KEY_FIND}, {"HELP", KEY_HELP}, @@ -847,8 +805,8 @@ struct { {"SCOMMAND", KEY_SCOMMAND}, {"SCOPY", KEY_SCOPY}, {"SCREATE", KEY_SCREATE}, - {"SDC", KEY_SDC }, - {"SDL", KEY_SDL }, + {"SDC", KEY_SDC}, + {"SDL", KEY_SDL}, {"SELECT", KEY_SELECT}, {"SEND", KEY_SEND}, {"SEOL", KEY_SEOL}, @@ -856,7 +814,7 @@ struct { {"SFIND", KEY_SFIND}, {"SHELP", KEY_SHELP}, {"SHOME", KEY_SHOME}, - {"SIC", KEY_SIC }, + {"SIC", KEY_SIC}, {"SLEFT", KEY_SLEFT}, {"SMESSAGE", KEY_SMESSAGE}, {"SMOVE", KEY_SMOVE}, @@ -890,7 +848,7 @@ int term_keycodeByName(const char *name) { return name[0]; } -static int term_ctrlPressed(int* key) { +static int term_ctrlPressed(int *key) { // The keycode representing the enter key depends on curses initialization settings. With the // current settings, it's represented as 13, so return `RETURN_KEY` instead. if (*key == 13) { @@ -900,7 +858,7 @@ static int term_ctrlPressed(int* key) { if (*key == '\t') { // Tab is represented as "^I" return 0; } - const char* str = keyname(*key); + const char *str = keyname(*key); if (str == NULL) { return 0; } @@ -918,18 +876,5 @@ static int term_ctrlPressed(int* key) { } } - -struct term_t Term = { - term_start, - term_end, - term_mvaddch, - term_refresh, - term_getkey, - term_wait, - term_has_key, - term_title, - term_resize, - term_keycodeByName, - term_ctrlPressed, - {KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_BACKSPACE, KEY_DC, KEY_F(12)} -}; +struct term_t Term + = {term_start, term_end, term_mvaddch, term_refresh, term_getkey, term_wait, term_has_key, term_title, term_resize, term_keycodeByName, term_ctrlPressed, {KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_BACKSPACE, KEY_DC, KEY_F(12)}}; diff --git a/src/platform/term.h b/src/platform/term.h index 4c280c45..f6241f96 100644 --- a/src/platform/term.h +++ b/src/platform/term.h @@ -5,7 +5,9 @@ #define TERM_NONE 0 #define TERM_MOUSE 100000 -typedef struct {float r, g, b;} fcolor; +typedef struct { + float r, g, b; +} fcolor; struct term_t { int (*start)(); void (*end)(); @@ -17,7 +19,7 @@ struct term_t { void (*title)(const char *); void (*resize)(int w, int h); int (*keycodeByName)(const char *); - int (*ctrlPressed)(int* key); + int (*ctrlPressed)(int *key); struct { int up, down, left, right, backspace, del, quit; @@ -34,4 +36,3 @@ struct term_t { extern struct term_t Term; #endif - diff --git a/src/platform/tiles.c b/src/platform/tiles.c index 96312073..21c1a8ad 100644 --- a/src/platform/tiles.c +++ b/src/platform/tiles.c @@ -4,46 +4,40 @@ #include "platform.h" #include "tiles.h" -#define PI 3.14159265358979323846 - -#define PNG_WIDTH 2048 // width (px) of the source PNG -#define PNG_HEIGHT 5568 // height (px) of the source PNG -#define TILE_WIDTH 128 // width (px) of a single tile in the source PNG -#define TILE_HEIGHT 232 // height (px) of a single tile in the source PNG -#define TILE_ROWS 24 // number of rows in the source PNG -#define TILE_COLS 16 // number of columns in the source PNG -#define TEXT_X_HEIGHT 100 // height (px) of the 'x' outline -#define TEXT_BASELINE 46 // height (px) of the blank space below the 'x' outline -#define MAX_TILE_SIZE 64 // maximum width or height (px) of screen tiles before we switch to linear interpolation - +#define PI 3.14159265358979323846 + +#define PNG_WIDTH 2048 // width (px) of the source PNG +#define PNG_HEIGHT 5568 // height (px) of the source PNG +#define TILE_WIDTH 128 // width (px) of a single tile in the source PNG +#define TILE_HEIGHT 232 // height (px) of a single tile in the source PNG +#define TILE_ROWS 24 // number of rows in the source PNG +#define TILE_COLS 16 // number of columns in the source PNG +#define TEXT_X_HEIGHT 100 // height (px) of the 'x' outline +#define TEXT_BASELINE 46 // height (px) of the blank space below the 'x' outline +#define MAX_TILE_SIZE 64 // maximum width or height (px) of screen tiles before we switch to linear interpolation // How each tile should be processed: // - 's' = stretch: tile stretches to fill the space // - 'f' = fit: preserve aspect ratio (but tile can stretch up to 20%) // - 't' = text: characters must line up vertically (max. stretch 40%) // - '#' = symbols: other Unicode characters (max. stretch 40%) -static const char TileProcessing[TILE_ROWS][TILE_COLS+1] = { - "ffffffffffffffff", "ssssssssssssssss", "#t##########t#t#", "tttttttttttt###t", - "#ttttttttttttttt", "ttttttttttt#####", "#ttttttttttttttt", "ttttttttttt#####", - "################", "################", "################", "################", - "tttttttttttttttt", "ttttttt#tttttttt", "tttttttttttttttt", "ttttttt#tttttttt", - "ffsfsfsffsssssss", "ssfsfsffffffffff", "fffffffffffffsff", "ffffffffffffffff", - "fsssfffffffffffs", "fsffffffffffffff", "ffffssssffssffff", "ffffsfffffssssff" -}; +static const char TileProcessing[TILE_ROWS][TILE_COLS + 1] = {"ffffffffffffffff", "ssssssssssssssss", "#t##########t#t#", "tttttttttttt###t", "#ttttttttttttttt", "ttttttttttt#####", "#ttttttttttttttt", "ttttttttttt#####", + "################", "################", "################", "################", "tttttttttttttttt", "ttttttt#tttttttt", "tttttttttttttttt", "ttttttt#tttttttt", + "ffsfsfsffsssssss", "ssfsfsffffffffff", "fffffffffffffsff", "ffffffffffffffff", "fsssfffffffffffs", "fsffffffffffffff", "ffffssssffssffff", "ffffsfffffssssff"}; typedef struct ScreenTile { short foreRed, foreGreen, foreBlue; // foreground color (0..100) short backRed, backGreen, backBlue; // background color (0..100) - short charIndex; // index of the glyph to draw - short needsRefresh; // true if the tile has changed since the last screen refresh, else false + short charIndex; // index of the glyph to draw + short needsRefresh; // true if the tile has changed since the last screen refresh, else false } ScreenTile; -static SDL_Window *Win = NULL; // the SDL window -static SDL_Surface *TilesPNG; // source PNG -static SDL_Texture *Textures[4]; // textures used by the renderer to draw tiles -static int numTextures = 0; // how many textures are available in `Textures` -static int8_t tilePadding[TILE_ROWS][TILE_COLS]; // how many black lines are at the top/bottom of each tile in the source PNG -static boolean tileEmpty[TILE_ROWS][TILE_COLS]; // true if a tile is completely black in the source PNG, else false +static SDL_Window *Win = NULL; // the SDL window +static SDL_Surface *TilesPNG; // source PNG +static SDL_Texture *Textures[4]; // textures used by the renderer to draw tiles +static int numTextures = 0; // how many textures are available in `Textures` +static int8_t tilePadding[TILE_ROWS][TILE_COLS]; // how many black lines are at the top/bottom of each tile in the source PNG +static boolean tileEmpty[TILE_ROWS][TILE_COLS]; // true if a tile is completely black in the source PNG, else false // How much should a corner of a tile be shifted by before its downscaling, to improve its sharpness. // The first two dimensions are the tile's coordinates (row and column, both zero-based). @@ -53,16 +47,14 @@ static boolean tileEmpty[TILE_ROWS][TILE_COLS]; // true if a tile is completel // The values stored in tileShifts are signed integers. Unit is 1/10th of a pixel. static int8_t tileShifts[TILE_ROWS][TILE_COLS][2][MAX_TILE_SIZE][3]; -static ScreenTile screenTiles[ROWS][COLS]; // buffer for the expected contents of the screen -static int baseTileWidth = -1; // width (px) of tiles in the smallest texture (`Textures[0]`) -static int baseTileHeight = -1; // height (px) of tiles in the smallest texture (`Textures[0]`) - - -int windowWidth = -1; // the SDL window's width (in "screen units", not pixels) -int windowHeight = -1; // the SDL window's height (in "screen units", not pixels) -boolean fullScreen = false; // true if the window should be full-screen, else false -boolean softwareRendering = false; // true if hardware acceleration is disabled (by choice or by force) +static ScreenTile screenTiles[ROWS][COLS]; // buffer for the expected contents of the screen +static int baseTileWidth = -1; // width (px) of tiles in the smallest texture (`Textures[0]`) +static int baseTileHeight = -1; // height (px) of tiles in the smallest texture (`Textures[0]`) +int windowWidth = -1; // the SDL window's width (in "screen units", not pixels) +int windowHeight = -1; // the SDL window's height (in "screen units", not pixels) +boolean fullScreen = false; // true if the window should be full-screen, else false +boolean softwareRendering = false; // true if hardware acceleration is disabled (by choice or by force) /// Prints the fatal error message provided by SDL then closes the app. static void sdlfatal(char *file, int line) { @@ -70,14 +62,12 @@ static void sdlfatal(char *file, int line) { exit(EXIT_STATUS_FAILURE_PLATFORM_ERROR); } - /// Prints the fatal error message provided by SDL_image then closes the app. static void imgfatal(char *file, int line) { fprintf(stderr, "Fatal SDL_image error (%s:%d): %s\n", file, line, IMG_GetError()); exit(EXIT_STATUS_FAILURE_PLATFORM_ERROR); } - #if !SDL_VERSION_ATLEAST(2, 0, 5) SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format) { @@ -88,7 +78,6 @@ SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, #endif - /// Returns the numbers of black lines at the top and bottom of a given glyph in the source PNG. /// /// For example, if the glyph has 30 black lines at the top and 40 at the bottom, the function @@ -105,9 +94,7 @@ static int getPadding(int row, int column) { for (int x = 0; x < TILE_WIDTH; x++) { int y1 = padding; int y2 = TILE_HEIGHT - padding - 1; - if (pixels[(x + column * TILE_WIDTH) + (y1 + row * TILE_HEIGHT) * PNG_WIDTH] & 0xffffffU || - pixels[(x + column * TILE_WIDTH) + (y2 + row * TILE_HEIGHT) * PNG_WIDTH] & 0xffffffU) - { + if (pixels[(x + column * TILE_WIDTH) + (y1 + row * TILE_HEIGHT) * PNG_WIDTH] & 0xffffffU || pixels[(x + column * TILE_WIDTH) + (y2 + row * TILE_HEIGHT) * PNG_WIDTH] & 0xffffffU) { return padding; } } @@ -115,7 +102,6 @@ static int getPadding(int row, int column) { return padding; } - /// Tells if a tile is completely empty (black) in the source PNG. static boolean isTileEmpty(int row, int column) { Uint32 *pixels = TilesPNG->pixels; // each pixel is encoded as 0xffRRGGBB @@ -129,7 +115,6 @@ static boolean isTileEmpty(int row, int column) { return true; } - /// Downscales a tile to the specified size. /// /// The downscaling is performed in linear color space, rather than in gamma-compressed space which would cause @@ -166,8 +151,8 @@ static boolean isTileEmpty(int row, int column) { /// static double downscaleTile(SDL_Surface *surface, int tileWidth, int tileHeight, int row, int column, boolean optimizing) { int8_t noShifts[3] = {0, 0, 0}; - int padding = tilePadding[row][column]; // how much blank spaces there is at the top and bottom of the source tile - char processing = TileProcessing[row][column]; // how should this tile be processed? + int padding = tilePadding[row][column]; // how much blank spaces there is at the top and bottom of the source tile + char processing = TileProcessing[row][column]; // how should this tile be processed? // Size of the area the glyph must fit into int fitWidth = max(1, baseTileWidth); @@ -214,11 +199,12 @@ static double downscaleTile(SDL_Surface *surface, int tileWidth, int tileHeight, // ... horizontally: - // horizontal coordinates on the source tile for the left border (stop0), 3 taps (stop1, 2, 3), and right border (stop4) + // horizontal coordinates on the source tile for the left border (stop0), 3 taps (stop1, 2, 3), and right border + // (stop4) stop0 = 0; - stop1 = TILE_WIDTH / 5; // 20% - stop2 = TILE_WIDTH / 2; // 50% - stop3 = TILE_WIDTH * 4/5; // 80% + stop1 = TILE_WIDTH / 5; // 20% + stop2 = TILE_WIDTH / 2; // 50% + stop3 = TILE_WIDTH * 4 / 5; // 80% stop4 = TILE_WIDTH; // corresponding coordinates on the target tile, taking into account centering and sub-pixel positioning @@ -230,26 +216,32 @@ static double downscaleTile(SDL_Surface *surface, int tileWidth, int tileHeight, map4 = map0 + glyphWidth; // now we can interpolate the horizontal coordinates for all pixels - for (int x = stop0; x < stop1; x++) scaledX[x] = map0 + (map1 - map0) * (x - stop0) / (stop1 - stop0); - for (int x = stop1; x < stop2; x++) scaledX[x] = map1 + (map2 - map1) * (x - stop1) / (stop2 - stop1); - for (int x = stop2; x < stop3; x++) scaledX[x] = map2 + (map3 - map2) * (x - stop2) / (stop3 - stop2); - for (int x = stop3; x < stop4; x++) scaledX[x] = map3 + (map4 - map3) * (x - stop3) / (stop4 - stop3); + for (int x = stop0; x < stop1; x++) + scaledX[x] = map0 + (map1 - map0) * (x - stop0) / (stop1 - stop0); + for (int x = stop1; x < stop2; x++) + scaledX[x] = map1 + (map2 - map1) * (x - stop1) / (stop2 - stop1); + for (int x = stop2; x < stop3; x++) + scaledX[x] = map2 + (map3 - map2) * (x - stop2) / (stop3 - stop2); + for (int x = stop3; x < stop4; x++) + scaledX[x] = map3 + (map4 - map3) * (x - stop3) / (stop4 - stop3); // ... vertically: if (processing == 't') { - // vertical coordinates on the source tile for the top edge (stop0), stem (stop1), "x" (stop2, stop3), and bottom edge (stop4) + // vertical coordinates on the source tile for the top edge (stop0), stem (stop1), "x" (stop2, stop3), and + // bottom edge (stop4) stop4 = TILE_HEIGHT; stop3 = stop4 - TEXT_BASELINE; stop2 = stop3 - TEXT_X_HEIGHT; stop1 = stop2 / 3; stop0 = 0; } else { - // vertical coordinates on the source tile for the top edge (stop0), 3 taps (stop1, 2, 3), and bottom edge (stop4) + // vertical coordinates on the source tile for the top edge (stop0), 3 taps (stop1, 2, 3), and bottom edge + // (stop4) stop0 = 0; - stop1 = TILE_HEIGHT / 5; // 20% - stop2 = TILE_HEIGHT / 2; // 50% - stop3 = TILE_HEIGHT * 4/5; // 80% + stop1 = TILE_HEIGHT / 5; // 20% + stop2 = TILE_HEIGHT / 2; // 50% + stop3 = TILE_HEIGHT * 4 / 5; // 80% stop4 = TILE_HEIGHT; } @@ -275,12 +267,18 @@ static double downscaleTile(SDL_Surface *surface, int tileWidth, int tileHeight, map3 += shifts[1] * 0.1; // finally we can interpolate the vertical coordinates for all pixels - for (int y = 0; y < stop0; y++) scaledY[y] = -1; // not mapped (can happen with fitted tiles) - for (int y = stop0; y < stop1; y++) scaledY[y] = map0 + (map1 - map0) * (y - stop0) / (stop1 - stop0); - for (int y = stop1; y < stop2; y++) scaledY[y] = map1 + (map2 - map1) * (y - stop1) / (stop2 - stop1); - for (int y = stop2; y < stop3; y++) scaledY[y] = map2 + (map3 - map2) * (y - stop2) / (stop3 - stop2); - for (int y = stop3; y < stop4; y++) scaledY[y] = map3 + (map4 - map3) * (y - stop3) / (stop4 - stop3); - for (int y = stop4; y < TILE_HEIGHT; y++) scaledY[y] = -1; // not mapped (can happen with fitted tiles) + for (int y = 0; y < stop0; y++) + scaledY[y] = -1; // not mapped (can happen with fitted tiles) + for (int y = stop0; y < stop1; y++) + scaledY[y] = map0 + (map1 - map0) * (y - stop0) / (stop1 - stop0); + for (int y = stop1; y < stop2; y++) + scaledY[y] = map1 + (map2 - map1) * (y - stop1) / (stop2 - stop1); + for (int y = stop2; y < stop3; y++) + scaledY[y] = map2 + (map3 - map2) * (y - stop2) / (stop3 - stop2); + for (int y = stop3; y < stop4; y++) + scaledY[y] = map3 + (map4 - map3) * (y - stop3) / (stop4 - stop3); + for (int y = stop4; y < TILE_HEIGHT; y++) + scaledY[y] = -1; // not mapped (can happen with fitted tiles) // downscale source tile to accumulator for (int y0 = 0; y0 < TILE_HEIGHT; y0++) { @@ -296,19 +294,18 @@ static double downscaleTile(SDL_Surface *surface, int tileWidth, int tileHeight, // interpolate skipped lines, if any if (y1 >= 2 && y0 >= 1 && scaledY[y0 - 1] == y1 - 2) { for (int x1 = 0; x1 < tileWidth; x1++) { - dst[x1 - tileWidth] = dst[x1 - 2*tileWidth] + dst[x1]; + dst[x1 - tileWidth] = dst[x1 - 2 * tileWidth] + dst[x1]; } } } - downscaled: +downscaled: // procedural wall tops: diagonal sine waves if ((row == 16 && column == 2 || row == 21 && column == 1 || row == 22 && column == 4) && !optimizing) { for (int y = 0; y < tileHeight; y++) { if (row != 21 && (y > tileHeight / 2 || (values[y * tileWidth] & 0xffffffffU))) break; for (int x = 0; x < tileWidth; x++) { - double value = sin(2. * PI * ((double)x / tileWidth * numHorizWaves - + (double)y / tileHeight * numVertWaves)) / 2. + 0.5; + double value = sin(2. * PI * ((double)x / tileWidth * numHorizWaves + (double)y / tileHeight * numVertWaves)) / 2. + 0.5; values[y * tileWidth + x] = (uint64_t)round(255 * 255 * value * value) | 0x100000000U; } } @@ -325,11 +322,11 @@ static double downscaleTile(SDL_Surface *surface, int tileWidth, int tileHeight, value = ((value >> 32) ? (value & 0xffffffffU) / (value >> 32) : 0); // metric for "blurriness": black (0) and white (255*255) pixels count for 0, gray pixels for 1 - if (optimizing) blur += sin(PI/(255*255) * value); + if (optimizing) blur += sin(PI / (255 * 255) * value); // make text look less bold, at the cost of accuracy if (processing == 't' || processing == '#') { - value = (value < 255*255/2 ? value / 2 : value * 3/2 - 255*255/2); + value = (value < 255 * 255 / 2 ? value / 2 : value * 3 / 2 - 255 * 255 / 2); } // opacity (gamma-compressed, 0 .. 255) @@ -343,7 +340,6 @@ static double downscaleTile(SDL_Surface *surface, int tileWidth, int tileHeight, return blur; // (used by the optimizer) } - /// Finds the best possible sub-pixel alignments of tiles for their downscaling at every possible size. /// Results are recorded into `tileShifts`. /// @@ -363,8 +359,8 @@ static void optimizeTiles() { SDL_SetWindowTitle(window, title); SDL_Surface *winSurface = SDL_GetWindowSurface(window); if (!winSurface) sdlfatal(__FILE__, __LINE__); - if (SDL_BlitSurface(TilesPNG, &(SDL_Rect){.x=column*TILE_WIDTH, .y=row*TILE_HEIGHT, .w=TILE_WIDTH, .h=TILE_HEIGHT}, - winSurface, &(SDL_Rect){.x=0, .y=0, .w=TILE_WIDTH, .h=TILE_HEIGHT}) < 0) sdlfatal(__FILE__, __LINE__); + if (SDL_BlitSurface(TilesPNG, &(SDL_Rect){.x = column * TILE_WIDTH, .y = row * TILE_HEIGHT, .w = TILE_WIDTH, .h = TILE_HEIGHT}, winSurface, &(SDL_Rect){.x = 0, .y = 0, .w = TILE_WIDTH, .h = TILE_HEIGHT}) < 0) + sdlfatal(__FILE__, __LINE__); if (SDL_UpdateWindowSurface(window) < 0) sdlfatal(__FILE__, __LINE__); // detect closing the window @@ -441,7 +437,6 @@ static void optimizeTiles() { SDL_DestroyWindow(window); } - /// Loads the PNG and analyses it. void initTiles() { char filename[BROGUE_FILENAME_MAX]; @@ -487,7 +482,6 @@ void initTiles() { } } - /// Creates the textures to fit a specific output size /// (which is equal to the window size on standard DPI displays, but can be larger on HiDPI). /// @@ -554,8 +548,10 @@ static void createTextures(SDL_Renderer *renderer, int outputWidth, int outputHe int tileWidth = baseTileWidth + (i == 1 || i == 3 ? 1 : 0); int tileHeight = baseTileHeight + (i == 2 || i == 3 ? 1 : 0); int surfaceWidth = 1, surfaceHeight = 1; - while (surfaceWidth < tileWidth * TILE_COLS) surfaceWidth *= 2; - while (surfaceHeight < tileHeight * TILE_ROWS) surfaceHeight *= 2; + while (surfaceWidth < tileWidth * TILE_COLS) + surfaceWidth *= 2; + while (surfaceHeight < tileHeight * TILE_ROWS) + surfaceHeight *= 2; // downscale the tiles SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, surfaceWidth, surfaceHeight, 32, SDL_PIXELFORMAT_ARGB8888); @@ -574,7 +570,6 @@ static void createTextures(SDL_Renderer *renderer, int outputWidth, int outputHe } } - /// Updates the screen buffer. /// /// \param row row on screen (between 0 and ROWS-1) @@ -587,23 +582,10 @@ static void createTextures(SDL_Renderer *renderer, int outputWidth, int outputHe /// \param backGreen green component of the background color (0..100) /// \param backBlue blue component of the background color (0..100) /// -void updateTile(int row, int column, short charIndex, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue) -{ - screenTiles[row][column] = (ScreenTile){ - .foreRed = foreRed, - .foreGreen = foreGreen, - .foreBlue = foreBlue, - .backRed = backRed, - .backGreen = backGreen, - .backBlue = backBlue, - .charIndex = charIndex, - .needsRefresh = 1 - }; +void updateTile(int row, int column, short charIndex, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue) { + screenTiles[row][column] = (ScreenTile){.foreRed = foreRed, .foreGreen = foreGreen, .foreBlue = foreBlue, .backRed = backRed, .backGreen = backGreen, .backBlue = backBlue, .charIndex = charIndex, .needsRefresh = 1}; } - /// Draws everything on screen. /// /// OpenGL drivers don't like alternating between different textures too much, so we @@ -656,11 +638,11 @@ void updateScreen() { for (int step = -1; step < numTextures; step++) { for (int x = 0; x < COLS; x++) { - int tileWidth = ((x+1) * outputWidth / COLS) - (x * outputWidth / COLS); + int tileWidth = ((x + 1) * outputWidth / COLS) - (x * outputWidth / COLS); if (tileWidth == 0) continue; for (int y = 0; y < ROWS; y++) { - int tileHeight = ((y+1) * outputHeight / ROWS) - (y * outputHeight / ROWS); + int tileHeight = ((y + 1) * outputHeight / ROWS) - (y * outputHeight / ROWS); if (tileHeight == 0) continue; ScreenTile *tile = &screenTiles[y][x]; @@ -680,10 +662,7 @@ void updateScreen() { dest.y = y * outputHeight / ROWS; // paint the background - if (SDL_SetRenderDrawColor(renderer, - round(2.55 * tile->backRed), - round(2.55 * tile->backGreen), - round(2.55 * tile->backBlue), 255) < 0) sdlfatal(__FILE__, __LINE__); + if (SDL_SetRenderDrawColor(renderer, round(2.55 * tile->backRed), round(2.55 * tile->backGreen), round(2.55 * tile->backBlue), 255) < 0) sdlfatal(__FILE__, __LINE__); if (SDL_RenderFillRect(renderer, &dest) < 0) sdlfatal(__FILE__, __LINE__); } else { @@ -692,16 +671,15 @@ void updateScreen() { continue; // this tile uses another texture and gets painted at another step } - int tileRow = tile->charIndex / 16; + int tileRow = tile->charIndex / 16; int tileColumn = tile->charIndex % 16; - if (tileEmpty[tileRow][tileColumn] - && !(tileRow == 21 && tileColumn == 1)) { // wall top (procedural) - continue; // there is nothing to draw + if (tileEmpty[tileRow][tileColumn] && !(tileRow == 21 && tileColumn == 1)) { // wall top (procedural) + continue; // there is nothing to draw } SDL_Rect src; - src.w = baseTileWidth + (step == 1 || step == 3 ? 1 : 0); + src.w = baseTileWidth + (step == 1 || step == 3 ? 1 : 0); src.h = baseTileHeight + (step == 2 || step == 3 ? 1 : 0); src.x = src.w * tileColumn; src.y = src.h * tileRow; @@ -713,10 +691,7 @@ void updateScreen() { dest.y = y * outputHeight / ROWS; // blend the foreground - if (SDL_SetTextureColorMod(Textures[step], - round(2.55 * tile->foreRed), - round(2.55 * tile->foreGreen), - round(2.55 * tile->foreBlue)) < 0) sdlfatal(__FILE__, __LINE__); + if (SDL_SetTextureColorMod(Textures[step], round(2.55 * tile->foreRed), round(2.55 * tile->foreGreen), round(2.55 * tile->foreBlue)) < 0) sdlfatal(__FILE__, __LINE__); if (SDL_RenderCopy(renderer, Textures[step], &src, &dest) < 0) sdlfatal(__FILE__, __LINE__); } } @@ -733,7 +708,6 @@ void updateScreen() { } } - /* Creates or resizes the game window with the currently loaded font. */ @@ -744,17 +718,15 @@ void resizeWindow(int width, int height) { // By default the window will have an aspect ratio of 16:10 // and either 80% of monitor width or 80% of monitor height, whichever is smaller - if (width < 0) width = min(mode.w * 8/10, mode.h * 8*16/(10*10)); - if (height < 0) height = width * 10/16; + if (width < 0) width = min(mode.w * 8 / 10, mode.h * 8 * 16 / (10 * 10)); + if (height < 0) height = width * 10 / 16; // go to fullscreen mode if the window is as big as the screen if (width >= mode.w && height >= mode.h) fullScreen = true; if (Win == NULL) { // create the window - Win = SDL_CreateWindow("Brogue", - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | (fullScreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); + Win = SDL_CreateWindow("Brogue", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | (fullScreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); if (!Win) sdlfatal(__FILE__, __LINE__); // set its icon @@ -791,7 +763,6 @@ void resizeWindow(int width, int height) { updateScreen(); } - SDL_Surface *captureScreen() { if (!Win) return NULL; diff --git a/src/platform/tiles.h b/src/platform/tiles.h index 6e54455a..fe8aa893 100644 --- a/src/platform/tiles.h +++ b/src/platform/tiles.h @@ -5,9 +5,7 @@ void initTiles(); void resizeWindow(int width, int height); -void updateTile(int row, int column, short charIndex, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue); +void updateTile(int row, int column, short charIndex, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue); void updateScreen(); SDL_Surface *captureScreen(); diff --git a/src/platform/web-platform.c b/src/platform/web-platform.c index 2b1ce331..b444f3bf 100644 --- a/src/platform/web-platform.c +++ b/src/platform/web-platform.c @@ -27,17 +27,10 @@ #define MOUSE_INPUT_SIZE 4 #define OUTPUT_BUFFER_SIZE 1000 -//Custom events +// Custom events #define REFRESH_SCREEN 50 -enum StatusTypes -{ - DEEPEST_LEVEL_STATUS, - GOLD_STATUS, - SEED_STATUS, - EASY_MODE_STATUS, - STATUS_TYPES_NUMBER -}; +enum StatusTypes { DEEPEST_LEVEL_STATUS, GOLD_STATUS, SEED_STATUS, EASY_MODE_STATUS, STATUS_TYPES_NUMBER }; extern playerCharacter rogue; static struct sockaddr_un addr_write; @@ -72,15 +65,12 @@ static void gameLoop() { static void openLogfile() { logfile = fopen("brogue-web.txt", "a"); - if (logfile == NULL) - { + if (logfile == NULL) { fprintf(stderr, "Logfile not created, errno = %d\n", errno); } } -static void closeLogfile() { - fclose(logfile); -} +static void closeLogfile() { fclose(logfile); } static void writeToLog(const char *msg) { fprintf(logfile, "%s", msg); @@ -108,9 +98,7 @@ static void setupSockets() { strncpy(addr_write.sun_path, CLIENT_SOCKET, sizeof(addr_write.sun_path) - 1); } -int readFromSocket(unsigned char *buf, int size) { - return recvfrom(rfd, buf, size, 0, NULL, NULL); -} +int readFromSocket(unsigned char *buf, int size) { return recvfrom(rfd, buf, size, 0, NULL, NULL); } static void flushOutputBuffer() { char msg[80]; @@ -128,8 +116,7 @@ static void flushOutputBuffer() { outputBufferPos = 0; } -static void writeToSocket(unsigned char *buf, int size) -{ +static void writeToSocket(unsigned char *buf, int size) { if (outputBufferPos + size > OUTPUT_BUFFER_SIZE) { flushOutputBuffer(); } @@ -141,18 +128,20 @@ static void writeToSocket(unsigned char *buf, int size) // Map characters which are missing or rendered as emoji on some platforms static unsigned int fixUnicode(unsigned int code) { switch (code) { - case U_ARIES: return 0x03C8; - case U_CIRCLE: return 'o'; - case U_CIRCLE_BARS: return 0x25C6; - case U_FILLED_CIRCLE_BARS: return 0x25C7; - default: return code; + case U_ARIES: + return 0x03C8; + case U_CIRCLE: + return 'o'; + case U_CIRCLE_BARS: + return 0x25C6; + case U_FILLED_CIRCLE_BARS: + return 0x25C7; + default: + return code; } } -static void web_plotChar(enum displayGlyph inputChar, - short xLoc, short yLoc, - short foreRed, short foreGreen, short foreBlue, - short backRed, short backGreen, short backBlue) { +static void web_plotChar(enum displayGlyph inputChar, short xLoc, short yLoc, short foreRed, short foreGreen, short foreBlue, short backRed, short backGreen, short backBlue) { unsigned char outputBuffer[OUTPUT_SIZE]; unsigned char firstCharByte, secondCharByte; enum displayGlyph translatedChar; @@ -190,7 +179,8 @@ static void sendStatusUpdate() { memset(statusOutputBuffer, 0, OUTPUT_SIZE); for (i = 0; i < STATUS_TYPES_NUMBER; i++) { - // Coordinates of (255, 255) will let the server and client know that this is a status update rather than a cell update + // Coordinates of (255, 255) will let the server and client know that this is a status update rather than a cell + // update statusOutputBuffer[0] = 255; statusOutputBuffer[1] = 255; @@ -231,7 +221,8 @@ static void web_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, unsigned char inputBuffer[MAX_INPUT_SIZE]; unsigned short keyCharacter; - // Because we will halt execution until we get more input, we definitely cannot have any dancing colors from the server side. + // Because we will halt execution until we get more input, we definitely cannot have any dancing colors from the + // server side. colorsDance = false; // Send a status update of game variables we want on the client @@ -269,8 +260,8 @@ static void web_nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, returnEvent->shiftKey = inputBuffer[4]; } else { // Mouse event fread(inputBuffer, sizeof(char), MOUSE_INPUT_SIZE, stdin); - returnEvent->param1 = inputBuffer[1]; //x coord - returnEvent->param2 = inputBuffer[2]; //y coord + returnEvent->param1 = inputBuffer[1]; // x coord + returnEvent->param2 = inputBuffer[2]; // y coord returnEvent->controlKey = inputBuffer[3]; returnEvent->shiftKey = inputBuffer[4]; } @@ -288,7 +279,8 @@ static boolean web_modifierHeld(int modifier) { static void web_notifyEvent(short eventId, int data1, int data2, const char *str1, const char *str2) { unsigned char statusOutputBuffer[EVENT_SIZE]; - // Coordinates of (254, 254) will let the server and client know that this is a event notification update rather than a cell update + // Coordinates of (254, 254) will let the server and client know that this is a event notification update rather + // than a cell update statusOutputBuffer[0] = 254; statusOutputBuffer[1] = 254; @@ -322,14 +314,4 @@ static void web_notifyEvent(short eventId, int data1, int data2, const char *str flushOutputBuffer(); } -struct brogueConsole webConsole = { - gameLoop, - web_pauseForMilliseconds, - web_nextKeyOrMouseEvent, - web_plotChar, - web_remap, - web_modifierHeld, - web_notifyEvent, - NULL, - NULL -}; +struct brogueConsole webConsole = {gameLoop, web_pauseForMilliseconds, web_nextKeyOrMouseEvent, web_plotChar, web_remap, web_modifierHeld, web_notifyEvent, NULL, NULL};