Migrate to 5e saving throws

This commit is contained in:
kinther 2025-10-03 19:38:42 -07:00
parent 19682f5b58
commit 7c9e1ea2fd
16 changed files with 297 additions and 788 deletions

View file

@ -1238,9 +1238,17 @@ static void do_stat_character(struct char_data *ch, struct char_data *k)
CCCYN(ch, C_NRM), CCYEL(ch, C_NRM), GET_SCREEN_WIDTH(k), CCNRM(ch, C_NRM),
CCYEL(ch, C_NRM), GET_PAGE_LENGTH(k), CCCYN(ch, C_NRM), CCNRM(ch, C_NRM));
send_to_char(ch, "AC: [%d%+d/10], Saving throws: [%d/%d/%d/%d/%d]\r\n",
GET_AC(k), GET_ABILITY_MOD(GET_DEX(k)), GET_SAVE(k, 0), GET_SAVE(k, 1), GET_SAVE(k, 2),
GET_SAVE(k, 3), GET_SAVE(k, 4));
send_to_char(ch,
"AC: [%d%+d/10], \r\n"
"Saving throws: STR[%d] DEX[%d] CON[%d] INT[%d] WIS[%d] CHA[%d]\r\n",
GET_AC(k),
GET_ABILITY_MOD(GET_DEX(k)),
GET_SAVE(k, ABIL_STR),
GET_SAVE(k, ABIL_DEX),
GET_SAVE(k, ABIL_CON),
GET_SAVE(k, ABIL_INT),
GET_SAVE(k, ABIL_WIS),
GET_SAVE(k, ABIL_CHA));
sprinttype(GET_POS(k), position_types, buf, sizeof(buf));
send_to_char(ch, "Pos: %s, Fighting: %s", buf, FIGHTING(k) ? GET_NAME(FIGHTING(k)) : "Nobody");
@ -4018,11 +4026,12 @@ static struct zcheck_affs {
{APPLY_GOLD, 0, 0, "gold"},
{APPLY_EXP, 0, 0, "experience"},
{APPLY_AC, -10, 10, "magical AC"},
{APPLY_SAVING_PARA, -2, 2, "saving throw (paralysis)"},
{APPLY_SAVING_ROD, -2, 2, "saving throw (rod)"},
{APPLY_SAVING_PETRI,-2, 2, "saving throw (death)"},
{APPLY_SAVING_BREATH,-2, 2, "saving throw (breath)"},
{APPLY_SAVING_SPELL,-2, 2, "saving throw (spell)"}
{APPLY_SAVE_STR, -2, 2, "saving throw (Strength)"},
{APPLY_SAVE_DEX, -2, 2, "saving throw (Dexterity)"},
{APPLY_SAVE_CON, -2, 2, "saving throw (Constitution)"},
{APPLY_SAVE_INT, -2, 2, "saving throw (Intelligence)"},
{APPLY_SAVE_WIS, -2, 2, "saving throw (Wisdom)"},
{APPLY_SAVE_CHA, -2, 2, "saving throw (Charisma)"}
};
/*room limits*/

View file

@ -141,14 +141,14 @@ int prac_params[4][NUM_CLASSES] = {
struct guild_info_type guild_info[] = {
/* Midgaard */
{ CLASS_SORCEROR, 3017, SOUTH },
{ CLASS_SORCEROR, 3017, SOUTH },
{ CLASS_CLERIC, 3004, NORTH },
{ CLASS_THIEF, 3027, EAST },
{ CLASS_FIGHTER, 3021, EAST },
{ CLASS_BARBARIAN, 3021, EAST },
{ CLASS_RANGER, 3021, EAST },
{ CLASS_BARD, 3021, EAST },
{ CLASS_DRUID, 3021, EAST },
{ CLASS_DRUID, 3021, EAST },
/* Brass Dragon */
{ -999 /* all */ , 5065, WEST },
@ -157,550 +157,19 @@ struct guild_info_type guild_info[] = {
{ -1, NOWHERE, -1}
};
/* Saving throws for : MCTW : PARA, ROD, PETRI, BREATH, SPELL. Levels 0-40. Do
* not forget to change extern declaration in magic.c if you add to this. */
byte saving_throws(int class_num, int type, int level)
{
/* 5e system saving throws per class*/
bool has_save_proficiency(int class_num, int ability) {
switch (class_num) {
case CLASS_SORCEROR:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 90;
case 1: return 70;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for mage paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 90;
case 1: return 55;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for mage rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 90;
case 1: return 65;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for mage petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 90;
case 1: return 75;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for mage breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 90;
case 1: return 60;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for mage spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
break;
case CLASS_CLERIC:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 90;
case 1: return 60;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for cleric paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 90;
case 1: return 70;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for cleric rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 90;
case 1: return 65;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for cleric petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 90;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for cleric breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 90;
case 1: return 75;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for cleric spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
break;
case CLASS_THIEF:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 90;
case 1: return 65;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for thief paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 90;
case 1: return 70;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for thief rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 90;
case 1: return 60;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for thief petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 90;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for thief breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 90;
case 1: return 75;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for thief spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
break;
case CLASS_FIGHTER:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 90;
case 1: return 70;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for fighter paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 90;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for fighter rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 90;
case 1: return 75;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for fighter petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 90;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for fighter breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 90;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for fighter spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
case CLASS_BARBARIAN:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 80;
case 1: return 60;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for barbarian paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 90;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for barbarian rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 70;
case 1: return 65;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for barbarian petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 90;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for barbarian breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 90;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for barbarian spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
break;
case CLASS_RANGER:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 75;
case 1: return 70;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for ranger paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 85;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for ranger rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 80;
case 1: return 75;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for ranger petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 90;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for ranger breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 90;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for ranger spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
break;
case CLASS_BARD:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 90;
case 1: return 70;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for bard paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 85;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for bard rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 85;
case 1: return 75;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for bard petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 85;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for bard breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 85;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for bard spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
break;
case CLASS_DRUID:
switch (type) {
case SAVING_PARA: /* Paralyzation */
switch (level) {
case 0: return 75;
case 1: return 70;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for druid paralyzation saving throw.");
break;
}
case SAVING_ROD: /* Rods */
switch (level) {
case 0: return 80;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for druid rod saving throw.");
break;
}
case SAVING_PETRI: /* Petrification */
switch (level) {
case 0: return 90;
case 1: return 75;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for druid petrification saving throw.");
break;
}
case SAVING_BREATH: /* Breath weapons */
switch (level) {
case 0: return 90;
case 1: return 85;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for druid breath saving throw.");
break;
}
case SAVING_SPELL: /* Generic spells */
switch (level) {
case 0: return 85;
case 1: return 80;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
default:
log("SYSERR: Missing level for druid spell saving throw.");
break;
}
default:
log("SYSERR: Invalid saving throw type.");
break;
}
break;
case CLASS_SORCEROR: return (ability == ABIL_CON || ability == ABIL_CHA);
case CLASS_CLERIC: return (ability == ABIL_WIS || ability == ABIL_CHA);
case CLASS_THIEF: return (ability == ABIL_DEX || ability == ABIL_INT);
case CLASS_FIGHTER: return (ability == ABIL_STR || ability == ABIL_CON);
case CLASS_BARBARIAN: return (ability == ABIL_STR || ability == ABIL_CON);
case CLASS_RANGER: return (ability == ABIL_STR || ability == ABIL_DEX);
case CLASS_BARD: return (ability == ABIL_DEX || ability == ABIL_CHA);
case CLASS_DRUID: return (ability == ABIL_INT || ability == ABIL_WIS);
default: return FALSE;
}
/* Should not get here unless something is wrong. */
return 100;
}
/* Roll the 6 stats for a character... each stat is made of the sum of the best

View file

@ -21,7 +21,6 @@ int invalid_class(struct char_data *ch, struct obj_data *obj);
int level_exp(int chclass, int level);
int parse_class(char arg);
void roll_real_abils(struct char_data *ch);
byte saving_throws(int class_num, int type, int level);
const char *title_female(int chclass, int level);
const char *title_male(int chclass, int level);

View file

@ -513,11 +513,12 @@ const char *apply_types[] = {
"GOLD",
"EXP",
"ARMOR",
"SAVING_PARA",
"SAVING_ROD",
"SAVING_PETRI",
"SAVING_BREATH",
"SAVING_SPELL",
"SAVE_STR",
"SAVE_DEX",
"SAVE_CON",
"SAVE_INT",
"SAVE_WIS",
"SAVE_CHA",
"\n"
};

View file

@ -1658,29 +1658,35 @@ static void interpret_espec(const char *keyword, const char *value, int i, int n
mob_proto[i].real_abils.cha = num_arg;
}
CASE("SavingPara") {
/* --- New 5e-style saving throw keywords --- */
CASE("SaveStr") {
RANGE(0, 100);
mob_proto[i].char_specials.saved.apply_saving_throw[SAVING_PARA] = num_arg;
mob_proto[i].char_specials.saved.saving_throws[ABIL_STR] = num_arg;
}
CASE("SavingRod") {
CASE("SaveDex") {
RANGE(0, 100);
mob_proto[i].char_specials.saved.apply_saving_throw[SAVING_ROD] = num_arg;
mob_proto[i].char_specials.saved.saving_throws[ABIL_DEX] = num_arg;
}
CASE("SavingPetri") {
CASE("SaveCon") {
RANGE(0, 100);
mob_proto[i].char_specials.saved.apply_saving_throw[SAVING_PETRI] = num_arg;
mob_proto[i].char_specials.saved.saving_throws[ABIL_CON] = num_arg;
}
CASE("SavingBreath") {
CASE("SaveInt") {
RANGE(0, 100);
mob_proto[i].char_specials.saved.apply_saving_throw[SAVING_BREATH] = num_arg;
mob_proto[i].char_specials.saved.saving_throws[ABIL_INT] = num_arg;
}
CASE("SavingSpell") {
CASE("SaveWis") {
RANGE(0, 100);
mob_proto[i].char_specials.saved.apply_saving_throw[SAVING_SPELL] = num_arg;
mob_proto[i].char_specials.saved.saving_throws[ABIL_WIS] = num_arg;
}
CASE("SaveCha") {
RANGE(0, 100);
mob_proto[i].char_specials.saved.saving_throws[ABIL_CHA] = num_arg;
}
if (!matched) {

View file

@ -970,40 +970,52 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
}
break;
case 's':
if (!str_cmp(field, "saving_breath")) {
if (!str_cmp(field, "save_str")) {
if (subfield && *subfield) {
int addition = atoi(subfield);
GET_SAVE(c, SAVING_BREATH) += addition;
GET_SAVE(c, ABIL_STR) += addition;
}
snprintf(str, slen, "%d", GET_SAVE(c, SAVING_BREATH));
snprintf(str, slen, "%d", GET_SAVE(c, ABIL_STR));
}
else if (!str_cmp(field, "saving_para")) {
else if (!str_cmp(field, "save_dex")) {
if (subfield && *subfield) {
int addition = atoi(subfield);
GET_SAVE(c, SAVING_PARA) += addition;
GET_SAVE(c, ABIL_DEX) += addition;
}
snprintf(str, slen, "%d", GET_SAVE(c, SAVING_PARA));
snprintf(str, slen, "%d", GET_SAVE(c, ABIL_DEX));
}
else if (!str_cmp(field, "saving_petri")) {
else if (!str_cmp(field, "save_con")) {
if (subfield && *subfield) {
int addition = atoi(subfield);
GET_SAVE(c, SAVING_PETRI) += addition;
GET_SAVE(c, ABIL_CON) += addition;
}
snprintf(str, slen, "%d", GET_SAVE(c, SAVING_PETRI));
snprintf(str, slen, "%d", GET_SAVE(c, ABIL_CON));
}
else if (!str_cmp(field, "saving_rod")) {
else if (!str_cmp(field, "save_int")) {
if (subfield && *subfield) {
int addition = atoi(subfield);
GET_SAVE(c, SAVING_ROD) += addition;
GET_SAVE(c, ABIL_INT) += addition;
}
snprintf(str, slen, "%d", GET_SAVE(c, SAVING_ROD));
snprintf(str, slen, "%d", GET_SAVE(c, ABIL_INT));
}
else if (!str_cmp(field, "saving_spell")) {
else if (!str_cmp(field, "save_wis")) {
if (subfield && *subfield) {
int addition = atoi(subfield);
GET_SAVE(c, SAVING_SPELL) += addition;
GET_SAVE(c, ABIL_WIS) += addition;
}
snprintf(str, slen, "%d", GET_SAVE(c, SAVING_SPELL));
snprintf(str, slen, "%d", GET_SAVE(c, ABIL_WIS));
}
else if (!str_cmp(field, "save_cha")) {
if (subfield && *subfield) {
int addition = atoi(subfield);
GET_SAVE(c, ABIL_CHA) += addition;
}
snprintf(str, slen, "%d", GET_SAVE(c, ABIL_CHA));
}
else if (!str_cmp(field, "sex"))
snprintf(str, slen, "%s", genders[(int)GET_SEX(c)]);

View file

@ -343,16 +343,21 @@ int write_mobile_espec(mob_vnum mvnum, struct char_data *mob, FILE *fd)
fprintf(fd, "Con: %d\n", GET_CON(mob));
if (GET_CHA(mob) != 11)
fprintf(fd, "Cha: %d\n", GET_CHA(mob));
if (GET_SAVE(mob, SAVING_PARA) != 0)
fprintf(fd, "SavingPara: %d\n", GET_SAVE(mob, SAVING_PARA));
if (GET_SAVE(mob, SAVING_ROD) != 0)
fprintf(fd, "SavingRod: %d\n", GET_SAVE(mob, SAVING_ROD));
if (GET_SAVE(mob, SAVING_PETRI) != 0)
fprintf(fd, "SavingPetri: %d\n", GET_SAVE(mob, SAVING_PETRI));
if (GET_SAVE(mob, SAVING_BREATH) != 0)
fprintf(fd, "SavingBreath: %d\n", GET_SAVE(mob, SAVING_BREATH));
if (GET_SAVE(mob, SAVING_SPELL) != 0)
fprintf(fd, "SavingSpell: %d\n", GET_SAVE(mob, SAVING_SPELL));
/* --- New ability-based saving throws --- */
if (GET_SAVE(mob, ABIL_STR) != 0)
fprintf(fd, "SaveStr: %d\n", GET_SAVE(mob, ABIL_STR));
if (GET_SAVE(mob, ABIL_DEX) != 0)
fprintf(fd, "SaveDex: %d\n", GET_SAVE(mob, ABIL_DEX));
if (GET_SAVE(mob, ABIL_CON) != 0)
fprintf(fd, "SaveCon: %d\n", GET_SAVE(mob, ABIL_CON));
if (GET_SAVE(mob, ABIL_INT) != 0)
fprintf(fd, "SaveInt: %d\n", GET_SAVE(mob, ABIL_INT));
if (GET_SAVE(mob, ABIL_WIS) != 0)
fprintf(fd, "SaveWis: %d\n", GET_SAVE(mob, ABIL_WIS));
if (GET_SAVE(mob, ABIL_CHA) != 0)
fprintf(fd, "SaveCha: %d\n", GET_SAVE(mob, ABIL_CHA));
fputs("E\n", fd);
return TRUE;
}

View file

@ -112,28 +112,16 @@ static void aff_apply_modify(struct char_data *ch, byte loc, sbyte mod, char *ms
case APPLY_NONE:
break;
case APPLY_STR:
GET_STR(ch) += mod;
break;
case APPLY_DEX:
GET_DEX(ch) += mod;
break;
case APPLY_INT:
GET_INT(ch) += mod;
break;
case APPLY_WIS:
GET_WIS(ch) += mod;
break;
case APPLY_CON:
GET_CON(ch) += mod;
break;
case APPLY_CHA:
GET_CHA(ch) += mod;
break;
/* --- ability scores --- */
case APPLY_STR: GET_STR(ch) += mod; break;
case APPLY_DEX: GET_DEX(ch) += mod; break;
case APPLY_INT: GET_INT(ch) += mod; break;
case APPLY_WIS: GET_WIS(ch) += mod; break;
case APPLY_CON: GET_CON(ch) += mod; break;
case APPLY_CHA: GET_CHA(ch) += mod; break;
/* Do Not Use. */
case APPLY_CLASS:
break;
case APPLY_LEVEL:
break;
@ -141,64 +129,28 @@ static void aff_apply_modify(struct char_data *ch, byte loc, sbyte mod, char *ms
ch->player.time.birth -= (mod * SECS_PER_MUD_YEAR);
break;
case APPLY_CHAR_WEIGHT:
GET_WEIGHT(ch) += mod;
break;
case APPLY_CHAR_WEIGHT: GET_WEIGHT(ch) += mod; break;
case APPLY_CHAR_HEIGHT: GET_HEIGHT(ch) += mod; break;
case APPLY_MANA: GET_MAX_MANA(ch) += mod; break;
case APPLY_HIT: GET_MAX_HIT(ch) += mod; break;
case APPLY_MOVE: GET_MAX_MOVE(ch) += mod; break;
case APPLY_GOLD: break;
case APPLY_EXP: break;
case APPLY_CHAR_HEIGHT:
GET_HEIGHT(ch) += mod;
break;
case APPLY_AC: GET_AC(ch) += mod; break;
case APPLY_PROFICIENCY: GET_PROF_MOD(ch) += mod; break;
case APPLY_MANA:
GET_MAX_MANA(ch) += mod;
break;
case APPLY_HIT:
GET_MAX_HIT(ch) += mod;
break;
case APPLY_MOVE:
GET_MAX_MOVE(ch) += mod;
break;
case APPLY_GOLD:
break;
case APPLY_EXP:
break;
case APPLY_AC:
GET_AC(ch) += mod;
break;
case APPLY_PROFICIENCY:
GET_PROF_MOD(ch) += mod;
break;
case APPLY_SAVING_PARA:
GET_SAVE(ch, SAVING_PARA) += mod;
break;
case APPLY_SAVING_ROD:
GET_SAVE(ch, SAVING_ROD) += mod;
break;
case APPLY_SAVING_PETRI:
GET_SAVE(ch, SAVING_PETRI) += mod;
break;
case APPLY_SAVING_BREATH:
GET_SAVE(ch, SAVING_BREATH) += mod;
break;
case APPLY_SAVING_SPELL:
GET_SAVE(ch, SAVING_SPELL) += mod;
break;
/* --- new 5e-style saving throws --- */
case APPLY_SAVE_STR: SAVE_STR(ch) += mod; break;
case APPLY_SAVE_DEX: SAVE_DEX(ch) += mod; break;
case APPLY_SAVE_CON: SAVE_CON(ch) += mod; break;
case APPLY_SAVE_INT: SAVE_INT(ch) += mod; break;
case APPLY_SAVE_WIS: SAVE_WIS(ch) += mod; break;
case APPLY_SAVE_CHA: SAVE_CHA(ch) += mod; break;
default:
log("SYSERR: Unknown apply adjust %d attempt (%s, affect_modify).", loc, __FILE__);
break;
} /* switch */
}

View file

@ -42,7 +42,7 @@ int mag_savingthrow(struct char_data *ch, int type, int modifier)
if (!IS_NPC(ch))
class_sav = GET_CLASS(ch);
save = saving_throws(class_sav, type, GET_LEVEL(ch));
save = GET_SAVE(ch, type);
save += GET_SAVE(ch, type);
save += modifier;
@ -321,10 +321,10 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
case SPELL_CHILL_TOUCH:
af[0].location = APPLY_STR;
if (mag_savingthrow(victim, savetype, 0))
af[0].duration = 1;
if (mag_savingthrow(victim, ABIL_CON, savetype))
af[0].duration = 1; /* resisted: brief weakening */
else
af[0].duration = 4;
af[0].duration = 4; /* failed: longer effect */
af[0].modifier = -1;
accum_duration = TRUE;
to_vict = "You feel your strength wither!";
@ -332,19 +332,20 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
case SPELL_ARMOR:
af[0].location = APPLY_AC;
af[0].modifier = -20;
af[0].modifier = +2; /* +2 AC in 5e terms */
af[0].duration = 24;
accum_duration = TRUE;
to_vict = "You feel someone protecting you.";
break;
case SPELL_BLESS:
af[0].location = GET_SPELL_ABILITY_MOD(ch);
af[0].modifier = 2;
af[0].location = APPLY_SAVE_WIS;
af[0].modifier = +1; /* bonus to Wisdom saves */
af[0].duration = 6;
af[1].location = APPLY_SAVING_SPELL;
af[1].modifier = -1;
/* Optional: extend to CHA saves if you want to emulate "morale" boost */
af[1].location = APPLY_SAVE_CHA;
af[1].modifier = +1;
af[1].duration = 6;
accum_duration = TRUE;
@ -352,18 +353,19 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
break;
case SPELL_BLINDNESS:
if (MOB_FLAGGED(victim, MOB_NOBLIND) || GET_LEVEL(victim) >= LVL_IMMORT || mag_savingthrow(victim, savetype, 0)) {
if (MOB_FLAGGED(victim, MOB_NOBLIND) || GET_LEVEL(victim) >= LVL_IMMORT ||
mag_savingthrow(victim, ABIL_CON, savetype)) {
send_to_char(ch, "You fail.\r\n");
return;
}
af[0].location = GET_SPELL_ABILITY_MOD(ch);
af[0].modifier = -4;
af[0].location = APPLY_SAVE_DEX; /* penalize Dex saves */
af[0].modifier = -2;
af[0].duration = 2;
SET_BIT_AR(af[0].bitvector, AFF_BLIND);
af[1].location = APPLY_AC;
af[1].modifier = 40;
af[1].location = APPLY_AC; /* easier to hit */
af[1].modifier = +40;
af[1].duration = 2;
SET_BIT_AR(af[1].bitvector, AFF_BLIND);
@ -372,17 +374,17 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
break;
case SPELL_CURSE:
if (mag_savingthrow(victim, savetype, 0)) {
if (mag_savingthrow(victim, ABIL_WIS, savetype)) {
send_to_char(ch, "%s", CONFIG_NOEFFECT);
return;
}
af[0].location = GET_SPELL_ABILITY_MOD(ch);
af[0].location = APPLY_SAVE_WIS; /* harder to resist magic */
af[0].duration = 1 + (GET_LEVEL(ch) / 2);
af[0].modifier = -1;
SET_BIT_AR(af[0].bitvector, AFF_CURSE);
af[1].location = GET_SPELL_ABILITY_MOD(ch);
af[1].location = APPLY_SAVE_CHA; /* morale/charisma weakened */
af[1].duration = 1 + (GET_LEVEL(ch) / 2);
af[1].modifier = -1;
SET_BIT_AR(af[1].bitvector, AFF_CURSE);
@ -434,7 +436,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
victim = ch;
af[0].duration = 12 + (GET_LEVEL(ch) / 4);
af[0].modifier = -40;
af[0].modifier = +2; /* ascending AC: harder to hit */
af[0].location = APPLY_AC;
SET_BIT_AR(af[0].bitvector, AFF_INVISIBLE);
accum_duration = TRUE;
@ -443,7 +445,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
break;
case SPELL_POISON:
if (mag_savingthrow(victim, savetype, 0)) {
if (mag_savingthrow(victim, ABIL_CON, savetype)) {
send_to_char(ch, "%s", CONFIG_NOEFFECT);
return;
}
@ -466,7 +468,6 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
case SPELL_SANCTUARY:
af[0].duration = 4;
SET_BIT_AR(af[0].bitvector, AFF_SANCTUARY);
accum_duration = TRUE;
to_vict = "A white aura momentarily surrounds you.";
to_room = "$n is surrounded by a white aura.";
@ -477,7 +478,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
return;
if (MOB_FLAGGED(victim, MOB_NOSLEEP))
return;
if (mag_savingthrow(victim, savetype, 0))
if (mag_savingthrow(victim, ABIL_WIS, savetype))
return;
af[0].duration = 4 + (GET_LEVEL(ch) / 4);
@ -496,14 +497,14 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
af[0].location = APPLY_STR;
af[0].duration = (GET_LEVEL(ch) / 2) + 4;
af[0].modifier = 1 + (level > 18);
af[0].modifier = 2; /* +2 bonus static */
accum_duration = TRUE;
accum_affect = TRUE;
to_vict = "You feel stronger!";
break;
case SPELL_SENSE_LIFE:
to_vict = "Your feel your awareness improve.";
to_vict = "You feel your awareness improve.";
af[0].duration = GET_LEVEL(ch);
SET_BIT_AR(af[0].bitvector, AFF_SENSE_LIFE);
accum_duration = TRUE;

View file

@ -222,6 +222,7 @@ void medit_setup_existing(struct descriptor_data *d, int rmob_num)
/* Ideally, this function should be in db.c, but I'll put it here for portability. */
static void init_mobile(struct char_data *mob)
{
int i;
clear_char(mob);
GET_HIT(mob) = GET_MANA(mob) = 1;
@ -234,11 +235,8 @@ static void init_mobile(struct char_data *mob)
mob->real_abils.dex = mob->real_abils.con = mob->real_abils.cha = 11;
mob->aff_abils = mob->real_abils;
GET_SAVE(mob, SAVING_PARA) = 0;
GET_SAVE(mob, SAVING_ROD) = 0;
GET_SAVE(mob, SAVING_PETRI) = 0;
GET_SAVE(mob, SAVING_BREATH) = 0;
GET_SAVE(mob, SAVING_SPELL) = 0;
for (i = 0; i < NUM_ABILITIES; i++)
GET_SAVE(mob, i) = 0;
SET_BIT_AR(MOB_FLAGS(mob), MOB_ISNPC);
mob->player_specials = &dummy_mob;
@ -491,19 +489,32 @@ static void medit_disp_stats_menu(struct descriptor_data *d)
if (CONFIG_MEDIT_ADVANCED) {
/* Bottom section - non-standard stats, togglable in cedit */
write_to_output(d,
"(%sF%s) Str: %s[%s%2d/%3d%s]%s Saving Throws\r\n"
"(%sG%s) Int: %s[%s%3d%s]%s (%sL%s) Paralysis %s[%s%3d%s]%s\r\n"
"(%sH%s) Wis: %s[%s%3d%s]%s (%sM%s) Rods/Staves %s[%s%3d%s]%s\r\n"
"(%sI%s) Dex: %s[%s%3d%s]%s (%sN%s) Petrification %s[%s%3d%s]%s\r\n"
"(%sJ%s) Con: %s[%s%3d%s]%s (%sO%s) Breath %s[%s%3d%s]%s\r\n"
"(%sK%s) Cha: %s[%s%3d%s]%s (%sP%s) Spells %s[%s%3d%s]%s\r\n\r\n",
" %sAttributes%s %sSaving Throws%s\r\n"
"(%sF%s) Str: %s[%s%2d/%3d%s]%s (%sR%s) Save STR %s[%s%3d%s]%s\r\n"
"(%sG%s) Int: %s[%s%3d%s]%s (%sS%s) Save DEX %s[%s%3d%s]%s\r\n"
"(%sH%s) Wis: %s[%s%3d%s]%s (%sT%s) Save CON %s[%s%3d%s]%s\r\n"
"(%sI%s) Dex: %s[%s%3d%s]%s (%sU%s) Save INT %s[%s%3d%s]%s\r\n"
"(%sJ%s) Con: %s[%s%3d%s]%s (%sV%s) Save WIS %s[%s%3d%s]%s\r\n"
"(%sK%s) Cha: %s[%s%3d%s]%s (%sW%s) Save CHA %s[%s%3d%s]%s\r\n\r\n",
nrm, cyn, nrm, cyn,
cyn, nrm, cyn, yel, GET_STR(mob), GET_ADD(mob), cyn, nrm,
cyn, nrm, cyn, yel, GET_INT(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_PARA), cyn, nrm,
cyn, nrm, cyn, yel, GET_WIS(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_ROD), cyn, nrm,
cyn, nrm, cyn, yel, GET_DEX(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_PETRI), cyn, nrm,
cyn, nrm, cyn, yel, GET_CON(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_BREATH), cyn, nrm,
cyn, nrm, cyn, yel, GET_CHA(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_SAVE(mob, SAVING_SPELL), cyn, nrm
);
cyn, nrm, cyn, yel, GET_SAVE(mob, ABIL_STR), cyn, nrm,
cyn, nrm, cyn, yel, GET_INT(mob), cyn, nrm,
cyn, nrm, cyn, yel, GET_SAVE(mob, ABIL_DEX), cyn, nrm,
cyn, nrm, cyn, yel, GET_WIS(mob), cyn, nrm,
cyn, nrm, cyn, yel, GET_SAVE(mob, ABIL_CON), cyn, nrm,
cyn, nrm, cyn, yel, GET_DEX(mob), cyn, nrm,
cyn, nrm, cyn, yel, GET_SAVE(mob, ABIL_INT), cyn, nrm,
cyn, nrm, cyn, yel, GET_CON(mob), cyn, nrm,
cyn, nrm, cyn, yel, GET_SAVE(mob, ABIL_WIS), cyn, nrm,
cyn, nrm, cyn, yel, GET_CHA(mob), cyn, nrm,
cyn, nrm, cyn, yel, GET_SAVE(mob, ABIL_CHA), cyn, nrm
);
}
/* Quit to previous menu option */
@ -751,45 +762,66 @@ void medit_parse(struct descriptor_data *d, char *arg)
write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
return;
}
OLC_MODE(d) = MEDIT_PARA;
i++;
break;
case 'm':
case 'M':
case 'r':
case 'R':
if (!CONFIG_MEDIT_ADVANCED) {
write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
return;
}
OLC_MODE(d) = MEDIT_ROD;
}
OLC_MODE(d) = MEDIT_SAVE_STR;
i++;
break;
case 'n':
case 'N':
case 's':
case 'S':
if (!CONFIG_MEDIT_ADVANCED) {
write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
return;
}
OLC_MODE(d) = MEDIT_PETRI;
}
OLC_MODE(d) = MEDIT_SAVE_DEX;
i++;
break;
case 'o':
case 'O':
case 't':
case 'T':
if (!CONFIG_MEDIT_ADVANCED) {
write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
return;
}
OLC_MODE(d) = MEDIT_BREATH;
}
OLC_MODE(d) = MEDIT_SAVE_CON;
i++;
break;
case 'p':
case 'P':
case 'u':
case 'U':
if (!CONFIG_MEDIT_ADVANCED) {
write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
return;
}
OLC_MODE(d) = MEDIT_SPELL;
}
OLC_MODE(d) = MEDIT_SAVE_INT;
i++;
break;
case 'v':
case 'V':
if (!CONFIG_MEDIT_ADVANCED) {
write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
return;
}
OLC_MODE(d) = MEDIT_SAVE_WIS;
i++;
break;
case 'w':
case 'W':
if (!CONFIG_MEDIT_ADVANCED) {
write_to_output(d, "Invalid Choice!\r\nEnter Choice : ");
return;
}
OLC_MODE(d) = MEDIT_SAVE_CHA;
i++;
break;
default:
medit_disp_stats_menu(d);
return;
@ -942,35 +974,29 @@ void medit_parse(struct descriptor_data *d, char *arg)
medit_disp_stats_menu(d);
return;
case MEDIT_PARA:
GET_SAVE(OLC_MOB(d), SAVING_PARA) = LIMIT(i, 0, 100);
OLC_VAL(d) = TRUE;
medit_disp_stats_menu(d);
return;
case MEDIT_SAVE_STR:
GET_SAVE(OLC_MOB(d), ABIL_STR) = LIMIT(atoi(arg), -20, 20);
break;
case MEDIT_ROD:
GET_SAVE(OLC_MOB(d), SAVING_ROD) = LIMIT(i, 0, 100);
OLC_VAL(d) = TRUE;
medit_disp_stats_menu(d);
return;
case MEDIT_SAVE_DEX:
GET_SAVE(OLC_MOB(d), ABIL_DEX) = LIMIT(atoi(arg), -20, 20);
break;
case MEDIT_PETRI:
GET_SAVE(OLC_MOB(d), SAVING_PETRI) = LIMIT(i, 0, 100);
OLC_VAL(d) = TRUE;
medit_disp_stats_menu(d);
return;
case MEDIT_SAVE_CON:
GET_SAVE(OLC_MOB(d), ABIL_CON) = LIMIT(atoi(arg), -20, 20);
break;
case MEDIT_BREATH:
GET_SAVE(OLC_MOB(d), SAVING_BREATH) = LIMIT(i, 0, 100);
OLC_VAL(d) = TRUE;
medit_disp_stats_menu(d);
return;
case MEDIT_SAVE_INT:
GET_SAVE(OLC_MOB(d), ABIL_INT) = LIMIT(atoi(arg), -20, 20);
break;
case MEDIT_SPELL:
GET_SAVE(OLC_MOB(d), SAVING_SPELL) = LIMIT(i, 0, 100);
OLC_VAL(d) = TRUE;
medit_disp_stats_menu(d);
return;
case MEDIT_SAVE_WIS:
GET_SAVE(OLC_MOB(d), ABIL_WIS) = LIMIT(atoi(arg), -20, 20);
break;
case MEDIT_SAVE_CHA:
GET_SAVE(OLC_MOB(d), ABIL_CHA) = LIMIT(atoi(arg), -20, 20);
break;
case MEDIT_POS:
GET_POS(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_POSITIONS - 1);
@ -1053,27 +1079,28 @@ void medit_autoroll_stats(struct descriptor_data *d)
mob_lev = GET_LEVEL(OLC_MOB(d));
mob_lev = GET_LEVEL(OLC_MOB(d)) = LIMIT(mob_lev, 1, LVL_IMPL);
GET_MOVE(OLC_MOB(d)) = mob_lev*10; /* hit point bonus (mobs don't use movement points */
GET_HIT(OLC_MOB(d)) = mob_lev/5; /* number of hitpoint dice */
GET_MANA(OLC_MOB(d)) = mob_lev/5; /* size of hitpoint dice */
GET_MOVE(OLC_MOB(d)) = mob_lev * 10; /* hit point bonus (mobs don't use movement points) */
GET_HIT(OLC_MOB(d)) = mob_lev / 5; /* number of hitpoint dice */
GET_MANA(OLC_MOB(d)) = mob_lev / 5; /* size of hitpoint dice */
GET_NDD(OLC_MOB(d)) = MAX(1, mob_lev/6); /* number damage dice 1-5 */
GET_SDD(OLC_MOB(d)) = MAX(2, mob_lev/6); /* size of damage dice 2-5 */
GET_NDD(OLC_MOB(d)) = MAX(1, mob_lev / 6); /* number damage dice 1-5 */
GET_SDD(OLC_MOB(d)) = MAX(2, mob_lev / 6); /* size of damage dice 2-5 */
/* 'Advanced' stats are only rolled if advanced options are enabled */
if (CONFIG_MEDIT_ADVANCED) {
GET_STR(OLC_MOB(d)) = LIMIT((mob_lev*2)/3, 11, 18); /* 2/3 level in range 11 to 18 */
GET_INT(OLC_MOB(d)) = LIMIT((mob_lev*2)/3, 11, 18);
GET_WIS(OLC_MOB(d)) = LIMIT((mob_lev*2)/3, 11, 18);
GET_DEX(OLC_MOB(d)) = LIMIT((mob_lev*2)/3, 11, 18);
GET_CON(OLC_MOB(d)) = LIMIT((mob_lev*2)/3, 11, 18);
GET_CHA(OLC_MOB(d)) = LIMIT((mob_lev*2)/3, 11, 18);
GET_STR(OLC_MOB(d)) = LIMIT((mob_lev * 2) / 3, 11, 18); /* 2/3 level in range 11 to 18 */
GET_INT(OLC_MOB(d)) = LIMIT((mob_lev * 2) / 3, 11, 18);
GET_WIS(OLC_MOB(d)) = LIMIT((mob_lev * 2) / 3, 11, 18);
GET_DEX(OLC_MOB(d)) = LIMIT((mob_lev * 2) / 3, 11, 18);
GET_CON(OLC_MOB(d)) = LIMIT((mob_lev * 2) / 3, 11, 18);
GET_CHA(OLC_MOB(d)) = LIMIT((mob_lev * 2) / 3, 11, 18);
GET_SAVE(OLC_MOB(d), SAVING_PARA) = mob_lev / 4; /* All Saving throws */
GET_SAVE(OLC_MOB(d), SAVING_ROD) = mob_lev / 4; /* set to a quarter */
GET_SAVE(OLC_MOB(d), SAVING_PETRI) = mob_lev / 4; /* of the mobs level */
GET_SAVE(OLC_MOB(d), SAVING_BREATH) = mob_lev / 4;
GET_SAVE(OLC_MOB(d), SAVING_SPELL) = mob_lev / 4;
/* New ability-based saving throws: all default to 1/4 of mob level */
GET_SAVE(OLC_MOB(d), ABIL_STR) = mob_lev / 4;
GET_SAVE(OLC_MOB(d), ABIL_DEX) = mob_lev / 4;
GET_SAVE(OLC_MOB(d), ABIL_CON) = mob_lev / 4;
GET_SAVE(OLC_MOB(d), ABIL_INT) = mob_lev / 4;
GET_SAVE(OLC_MOB(d), ABIL_WIS) = mob_lev / 4;
GET_SAVE(OLC_MOB(d), ABIL_CHA) = mob_lev / 4;
}
}

View file

@ -283,11 +283,12 @@ extern const char *nrm, *grn, *cyn, *yel;
#define MEDIT_DEX 27
#define MEDIT_CON 28
#define MEDIT_CHA 29
#define MEDIT_PARA 30
#define MEDIT_ROD 31
#define MEDIT_PETRI 32
#define MEDIT_BREATH 33
#define MEDIT_SPELL 34
#define MEDIT_SAVE_STR 30
#define MEDIT_SAVE_DEX 31
#define MEDIT_SAVE_CON 32
#define MEDIT_SAVE_INT 33
#define MEDIT_SAVE_WIS 34
#define MEDIT_SAVE_CHA 35
/* Submodes of SEDIT connectedness. */
#define SEDIT_MAIN_MENU 0

View file

@ -208,13 +208,13 @@ int call_magic(struct char_data *caster, struct char_data *cvict,
case CAST_SCROLL:
case CAST_POTION:
case CAST_WAND:
savetype = SAVING_ROD;
savetype = SAVING_WIS;
break;
case CAST_SPELL:
savetype = SAVING_SPELL;
savetype = SAVING_WIS;
break;
default:
savetype = SAVING_BREATH;
savetype = SAVING_DEX;
break;
}

View file

@ -143,7 +143,7 @@ ASPELL(spell_summon)
}
if (MOB_FLAGGED(victim, MOB_NOSUMMON) ||
(IS_NPC(victim) && mag_savingthrow(victim, SAVING_SPELL, 0))) {
(IS_NPC(victim) && mag_savingthrow(victim, SAVING_CHA, 0))) {
send_to_char(ch, "%s", SUMMON_FAIL);
return;
}
@ -269,7 +269,7 @@ ASPELL(spell_charm)
send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n");
else if (circle_follow(victim, ch))
send_to_char(ch, "Sorry, following in circles is not allowed.\r\n");
else if (mag_savingthrow(victim, SAVING_PARA, 0))
else if (mag_savingthrow(victim, SAVING_WIS, 0))
send_to_char(ch, "Your victim resists!\r\n");
else {
if (victim->master)

View file

@ -155,11 +155,15 @@
/* new attack types can be added here - up to TYPE_SUFFERING */
#define TYPE_SUFFERING 399
#define SAVING_PARA 0
#define SAVING_ROD 1
#define SAVING_PETRI 2
#define SAVING_BREATH 3
#define SAVING_SPELL 4
/* Saving throws for 5e-like system */
#define SAVING_STR 0
#define SAVING_DEX 1
#define SAVING_CON 2
#define SAVING_INT 3
#define SAVING_WIS 4
#define SAVING_CHA 5
#define NUM_SAVING_THROWS 6
/***
**Possible Targets:

View file

@ -464,13 +464,15 @@
#define APPLY_EXP 16 /**< Reserved */
#define APPLY_AC 17 /**< Apply to Armor Class */
#define APPLY_PROFICIENCY 18 /**< Apply to Proficiency Bonus */
#define APPLY_SAVING_PARA 19 /**< Apply to save throw: paralysis */
#define APPLY_SAVING_ROD 20 /**< Apply to save throw: rods */
#define APPLY_SAVING_PETRI 21 /**< Apply to save throw: petrif */
#define APPLY_SAVING_BREATH 22 /**< Apply to save throw: breath */
#define APPLY_SAVING_SPELL 23 /**< Apply to save throw: spells */
#define APPLY_SAVE_STR 19 /**< Apply to STR saving throws */
#define APPLY_SAVE_DEX 20 /**< Apply to DEX saving throws */
#define APPLY_SAVE_CON 21 /**< Apply to CON saving throws */
#define APPLY_SAVE_INT 22 /**< Apply to INT saving throws */
#define APPLY_SAVE_WIS 23 /**< Apply to WIS saving throws */
#define APPLY_SAVE_CHA 24 /**< Apply to CHA saving throws */
/** Total number of applies */
#define NUM_APPLIES 24
#define NUM_APPLIES 25
/* Equals the total number of SAVING_* defines in spells.h */
#define NUM_OF_SAVING_THROWS 5
@ -900,6 +902,17 @@ struct char_ability_data
sbyte cha; /**< Charisma */
};
/* Ability score indices for 5e-like system */
enum ability_scores {
ABIL_STR = 0,
ABIL_DEX = 1,
ABIL_CON = 2,
ABIL_INT = 3,
ABIL_WIS = 4,
ABIL_CHA = 5,
NUM_ABILITIES
};
/** Character 'points', or health statistics. */
struct char_point_data
{
@ -931,7 +944,7 @@ struct char_special_data_saved
long idnum; /**< PC's idnum; -1 for mobiles. */
int act[PM_ARRAY_MAX]; /**< act flags for NPC's; player flag for PC's */
int affected_by[AF_ARRAY_MAX]; /**< Bitvector for spells/skills affected by */
sh_int apply_saving_throw[5]; /**< Saving throw (Bonuses) */
sh_int saving_throws[NUM_ABILITIES]; /* STR, DEX, CON, INT, WIS, CHA */
};
/** Special playing constants shared by PCs and NPCs which aren't in pfile */

View file

@ -550,6 +550,16 @@ do \
/** Current charisma of ch. */
#define GET_CHA(ch) ((ch)->aff_abils.cha)
/* Definitions for 5e-like saving throws */
#define GET_SAVE(ch, i) ((ch)->char_specials.saved.saving_throws[(i)])
#define SAVE_STR(ch) GET_SAVE(ch, ABIL_STR)
#define SAVE_DEX(ch) GET_SAVE(ch, ABIL_DEX)
#define SAVE_CON(ch) GET_SAVE(ch, ABIL_CON)
#define SAVE_INT(ch) GET_SAVE(ch, ABIL_INT)
#define SAVE_WIS(ch) GET_SAVE(ch, ABIL_WIS)
#define SAVE_CHA(ch) GET_SAVE(ch, ABIL_CHA)
/** Experience points of ch. */
#define GET_EXP(ch) ((ch)->points.exp)
/** Armor class of ch. */
@ -589,7 +599,7 @@ do \
/** Who or what the ch is hunting. */
#define HUNTING(ch) ((ch)->char_specials.hunting)
/** Saving throw i for character ch. */
#define GET_SAVE(ch, i) ((ch)->char_specials.saved.apply_saving_throw[i])
#define GET_SAVE(ch, i) ((ch)->char_specials.saved.saving_throws[(i)])
/** Alignment value for ch. */
#define GET_ALIGNMENT(ch) ((ch)->char_specials.saved.alignment)