Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changes/issue-499.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-
Cursed items cannot be unequipped for 1000 turns, or until a remove curse is used.
Curses also stack, so equipping two cursed items in quick succession would require
2000 turns before either item can be unequipped.
2 changes: 2 additions & 0 deletions src/brogue/IO.c
Original file line number Diff line number Diff line change
Expand Up @@ -4548,6 +4548,8 @@ short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight)
"Lifespan",
"Shielded",
"Invisible",
"",
"Cursed",
};

if (y >= ROWS - 1) {
Expand Down
13 changes: 12 additions & 1 deletion src/brogue/Items.c
Original file line number Diff line number Diff line change
Expand Up @@ -6871,9 +6871,17 @@ static void magicMapCell(short x, short y) {
}
}

static boolean uncurse( item *theItem ) {
boolean uncurse( item *theItem ) {
if (theItem->flags & ITEM_CURSED) {

// Uncurse the item
theItem->flags &= ~ITEM_CURSED;

// Also reduce curse duration if it is equipped
if (theItem->flags & ITEM_EQUIPPED) {
// Need to leave 1 tick on the status in case multiple cursed items contributed to the debuf
player.status[STATUS_CURSED] = max( 1, player.status[STATUS_CURSED] - CURSED_ITEM_DURATION );
}
return true;
}
return false;
Expand Down Expand Up @@ -6924,6 +6932,7 @@ void readScroll(item *theItem) {
hadEffect |= uncurse(tempItem);
}
if (hadEffect) {
player.status[STATUS_CURSED] = 0;
message("your pack glows with a cleansing light, and a malevolent energy disperses.", 0);
} else {
message("your pack glows with a cleansing light, but nothing happens.", 0);
Expand Down Expand Up @@ -7683,6 +7692,8 @@ boolean equipItem(item *theItem, boolean force, item *unequipHint) {
break;
}
messageWithColor(buf1, &itemMessageColor, 0);
player.status[STATUS_CURSED] += CURSED_ITEM_DURATION;
player.maxStatus[STATUS_CURSED] = player.status[STATUS_CURSED];
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/brogue/Rogue.h
Original file line number Diff line number Diff line change
Expand Up @@ -2000,6 +2000,7 @@ enum statusEffects {
STATUS_SHIELDED,
STATUS_INVISIBLE,
STATUS_AGGRAVATING,
STATUS_CURSED,
NUMBER_OF_STATUS_EFFECTS,
};

Expand Down Expand Up @@ -2360,6 +2361,7 @@ typedef struct gameConstants {
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 curseDuration; // Duration of curses (additive)

const int fallDamageMin; // minimum for fall damage range
const int fallDamageMax; // maximum for fall damage range
Expand Down
14 changes: 14 additions & 0 deletions src/brogue/Time.c
Original file line number Diff line number Diff line change
Expand Up @@ -2100,6 +2100,7 @@ void autoRest() {
|| player.status[STATUS_NAUSEOUS]
|| player.status[STATUS_POISONED]
|| player.status[STATUS_DARKNESS]
|| player.status[STATUS_CURSED]
|| initiallyEmbedded)
&& !rogue.disturbed) {

Expand All @@ -2111,6 +2112,7 @@ void autoRest() {
|| player.status[STATUS_NAUSEOUS]
|| player.status[STATUS_POISONED]
|| player.status[STATUS_DARKNESS]
|| player.status[STATUS_CURSED]
|| cellHasTerrainFlag(player.loc, T_OBSTRUCTS_PASSABILITY))
&& !rogue.disturbed
&& (!initiallyEmbedded || cellHasTerrainFlag(player.loc, T_OBSTRUCTS_PASSABILITY))) {
Expand Down Expand Up @@ -2318,6 +2320,18 @@ void playerTurnEnded() {
}
}

// Countdown curse
if (player.status[STATUS_CURSED] > 0) {
player.status[STATUS_CURSED]--;
if (player.status[STATUS_CURSED] == 0) {
// When curse debuf ends, uncurse all equipment
if (rogue.weapon != NULL) rogue.weapon->flags &= ~ITEM_CURSED;
if (rogue.armor != NULL) rogue.armor->flags &= ~ITEM_CURSED;
if (rogue.ringLeft != NULL) rogue.ringLeft->flags &= ~ITEM_CURSED;
if (rogue.ringRight != NULL) rogue.ringRight->flags &= ~ITEM_CURSED;
}
}

if (player.status[STATUS_POISONED] > 0) {
player.status[STATUS_POISONED]--;
if (inflictDamage(NULL, &player, player.poisonAmount, &green, true)) {
Expand Down
1 change: 1 addition & 0 deletions src/variants/GlobalsBrogue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,7 @@ const gameConstants brogueGameConst = {
.onHitHallucinateDuration = 20,
.onHitWeakenDuration = 300,
.onHitMercyHealPercent = 50,
.curseDuration = 1000,

.weaponKillsToAutoID = 20,
.armorDelayToAutoID = 1000,
Expand Down