diff --git a/lib/world/mob/1.mob b/lib/world/mob/1.mob index cb3db9f..a3e9a19 100644 --- a/lib/world/mob/1.mob +++ b/lib/world/mob/1.mob @@ -9,23 +9,23 @@ His eyes have a bluish-tint to them with a small amount of green. One might call his stature bulky, as he has quite a bit of muscle. ~ 2122 0 0 0 0 0 0 0 0 E -1 3d20+40 1d1 +1 3d20+40 8 8 1 Str: 16 Dex: 14 Con: 14 E -L 17 127 1 -L 16 117 1 -L 15 117 1 -L 11 111 1 -L 10 107 1 -L 9 124 1 -L 8 115 1 -L 7 108 1 -L 6 110 1 -L 5 131 1 L 3 118 1 +L 5 131 1 +L 6 110 1 +L 7 108 1 +L 8 115 1 +L 9 124 1 +L 10 107 1 +L 11 111 1 +L 15 117 1 +L 16 117 1 +L 17 127 1 #101 slim lanky human soldier guard~ a slim, lanky human soldier~ @@ -38,23 +38,23 @@ dark hair has been pulled back behind her head, intensifying the sharpness of her nose. ~ 2122 0 0 0 0 0 0 0 0 E -1 3d20+40 1d1 +1 3d20+40 8 8 2 Str: 14 Dex: 18 Con: 14 E -L 3 118 1 -L 5 131 1 -L 6 110 1 -L 7 108 1 -L 8 115 1 -L 9 124 1 -L 10 107 1 -L 11 111 1 -L 15 117 1 -L 16 117 1 L 17 127 1 +L 16 117 1 +L 15 117 1 +L 11 111 1 +L 10 107 1 +L 9 124 1 +L 8 115 1 +L 7 108 1 +L 6 110 1 +L 5 131 1 +L 3 118 1 #102 barkeep stocky bald~ a stocky, bald barkeep~ @@ -67,14 +67,14 @@ hands are marred with minor cuts and scars from years of working in service to others. ~ 10 0 0 0 0 0 0 0 0 E -1 3d12+60 1d1 +1 3d12+60 8 8 1 Str: 18 Int: 12 Con: 18 E -L 9 112 1 L 14 113 1 +L 9 112 1 #103 woman lanky scarred~ the lanky, scarred woman~ @@ -88,7 +88,7 @@ descending to just above her shoulders. Her eyes are a light blue color and appear slightly bloodshot. ~ 10 0 0 0 0 0 0 0 0 E -1 3d8+60 1d2 +1 3d8+60 8 8 2 Str: 12 Dex: 14 diff --git a/src/act.wizard.c b/src/act.wizard.c index 9c9d112..fd7e763 100644 --- a/src/act.wizard.c +++ b/src/act.wizard.c @@ -1283,9 +1283,8 @@ static void do_stat_character(struct char_data *ch, struct char_data *k) } if (IS_MOB(k)) - send_to_char(ch, "Mob Spec-Proc: %s, NPC Bare Hand Dam: %dd%d\r\n", - (mob_index[GET_MOB_RNUM(k)].func ? get_spec_func_name(mob_index[GET_MOB_RNUM(k)].func) : "None"), - k->mob_specials.damnodice, k->mob_specials.damsizedice); + send_to_char(ch, "Mob Spec-Proc: %s\r\n", + (mob_index[GET_MOB_RNUM(k)].func ? get_spec_func_name(mob_index[GET_MOB_RNUM(k)].func) : "None")); for (i = 0, j = k->carrying; j; j = j->next_content, i++); send_to_char(ch, "Carried: weight: %d, items: %d; Items in: inventory: %d, ", IS_CARRYING_W(k), IS_CARRYING_N(k), i); @@ -4090,19 +4089,37 @@ ACMD (do_zcheck) "- Is level %d (limit: 1-%d)\r\n", GET_LEVEL(mob), MAX_LEVEL_ALLOWED); - /* avg. dam per round of combat */ - avg_dam = (((mob->mob_specials.damsizedice / 2.0))); - if (avg_dam>MAX_MOB_DAM_ALLOWED && (found=1)) - len += snprintf(buf + len, sizeof(buf) - len, - "- average damage of %4.1f is too high (limit: %d)\r\n", - avg_dam, MAX_MOB_DAM_ALLOWED); + /* --- 5e-style average unarmed damage check --- */ + { + int prof = 0; + int str_mod = GET_ABILITY_MOD(GET_STR(mob)); + int die_size; - if (mob->mob_specials.damsizedice == 1 && - mob->mob_specials.damnodice == 1 && - GET_LEVEL(mob) == 0 && - (found=1)) - len += snprintf(buf + len, sizeof(buf) - len, - "- Needs to be fixed - %sAutogenerate!%s\r\n", CCYEL(ch, C_NRM), CCNRM(ch, C_NRM)); + /* derive proficiency tier; mobs use their stored unarmed skill */ + prof = GET_PROFICIENCY(GET_SKILL(mob, SKILL_UNARMED)); + + switch (prof) { + case 0: die_size = 4; break; /* initial unarmed skill die size */ + case 1: die_size = 4; break; + case 2: die_size = 6; break; /* ~40 skill level */ + case 3: die_size = 6; break; + case 4: die_size = 8; break; /* ~80 skill level */ + case 5: die_size = 10; break; /* max skill level */ + default: die_size = 12; break; + } + + /* expected average damage = average roll + STR + proficiency */ + avg_dam = ((die_size + 1) / 2.0) + str_mod + prof; + + if (avg_dam > MAX_MOB_DAM_ALLOWED && (found=1)) + len += snprintf(buf + len, sizeof(buf) - len, + "- average unarmed damage of %4.1f is too high (limit: %d)\r\n", + avg_dam, MAX_MOB_DAM_ALLOWED); + + if (prof == 0 && str_mod <= 0 && (found=1)) + len += snprintf(buf + len, sizeof(buf) - len, + "- No unarmed combat proficiency set (add skill or weapon)\r\n"); + } if (MOB_FLAGGED(mob, MOB_AGGRESSIVE) && (MOB_FLAGGED(mob, MOB_AGGR_GOOD) || MOB_FLAGGED(mob, MOB_AGGR_EVIL) || MOB_FLAGGED(mob, MOB_AGGR_NEUTRAL)) && (found=1)) len += snprintf(buf + len, sizeof(buf) - len, diff --git a/src/db.c b/src/db.c index 54d0539..14a7676 100644 --- a/src/db.c +++ b/src/db.c @@ -1552,10 +1552,10 @@ static void parse_simple_mob(FILE *mob_f, int i, int nr) exit(1); } - if (sscanf(line, " %d %dd%d+%d %dd%d ", - t, t + 1, t + 2, t + 3, t + 4, t + 5) != 6) { + if (sscanf(line, " %d %dd%d+%d ", + t, t + 1, t + 2, t + 3) != 4) { log("SYSERR: Format error in mob #%d, first line after S flag\n" - "...expecting line of form '# #d#+# #d#'", nr); + "...expecting line of form '# #d#+#'", nr); exit(1); } @@ -1570,9 +1570,6 @@ static void parse_simple_mob(FILE *mob_f, int i, int nr) GET_MAX_MANA(mob_proto + i) = 10; GET_MAX_MOVE(mob_proto + i) = 50; - mob_proto[i].mob_specials.damnodice = t[4]; - mob_proto[i].mob_specials.damsizedice = t[5]; - if (!get_line(mob_f, line)) { log("SYSERR: Format error in last line of mob #%d\n" "...expecting line of form '# # #', but file ended!", nr); diff --git a/src/fight.c b/src/fight.c index 5c24c2d..579b79a 100644 --- a/src/fight.c +++ b/src/fight.c @@ -862,6 +862,32 @@ void hit(struct char_data *ch, struct char_data *victim, int type) if (!IS_NPC(ch)) attack_mod += GET_PROFICIENCY(GET_SKILL(ch, skillnum)); + /* --- UNARMED ATTACK HANDLING --- */ + if (!wielded) { + int prof_bonus = (!IS_NPC(ch)) ? GET_PROFICIENCY(GET_SKILL(ch, SKILL_UNARMED)) : 0; + int str_mod = GET_ABILITY_MOD(GET_STR(ch)); + int die_size; + + /* Simple scaling by proficiency tier */ + switch (prof_bonus) { + case 0: die_size = 4; break; /* untrained */ + case 1: die_size = 6; break; /* trained */ + case 2: die_size = 8; break; /* expert */ + default: die_size = 10; break; /* master or above */ + } + + /* NPC fallback scaling */ + if (IS_NPC(ch) && prof_bonus <= 0) { + prof_bonus = MIN(6, (GET_LEVEL(ch) / 4)); /* level scaling */ + } + + /* base damage roll for unarmed attacks */ + dam = dice(1, die_size) + str_mod + prof_bonus; + + /* mark attack type for damage() messaging */ + w_type = SKILL_UNARMED + TYPE_HIT; + } + /* Weapon magic (cap +3) */ if (wielded && GET_OBJ_TYPE(wielded) == ITEM_WEAPON) { int wmag = GET_OBJ_VAL(wielded, VAL_ARMOR_MAGIC_BONUS); @@ -886,8 +912,12 @@ void hit(struct char_data *ch, struct char_data *victim, int type) /* Apply result */ if (hit_success) { - /* Roll damage up front (needed for shield durability) */ - dam = roll_damage(ch, victim, wielded, w_type); + /* Roll damage up front (needed for shield durability) + * If we are unarmed, dam was already rolled above. + * If wielding a weapon, roll normally. + */ + if (wielded) + dam = roll_damage(ch, victim, wielded, w_type); /* --- SHIELD BLOCK CHECK --- * Only happens if an attack actually lands. diff --git a/src/genmob.c b/src/genmob.c index 9fb2d05..4b25d6e 100644 --- a/src/genmob.c +++ b/src/genmob.c @@ -387,14 +387,14 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd) fprintf(fd, "%s", convert_from_tabs(buf)); fprintf(fd, "%d %d %d %d %d %d %d %d %d E\n" - "%d %dd%d+%d %dd%d\n", + "%d %dd%d+%d\n", MOB_FLAGS(mob)[0], MOB_FLAGS(mob)[1], MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3], AFF_FLAGS(mob)[0], AFF_FLAGS(mob)[1], AFF_FLAGS(mob)[2], AFF_FLAGS(mob)[3], GET_ALIGNMENT(mob), GET_LEVEL(mob), GET_HIT(mob), - GET_MANA(mob), GET_MOVE(mob), GET_NDD(mob), GET_SDD(mob)); + GET_MANA(mob), GET_MOVE(mob)); fprintf(fd, "%d %d %d\n", GET_POS(mob), GET_DEFAULT_POS(mob), GET_SEX(mob) diff --git a/src/genmob.h b/src/genmob.h index 50bc717..db747d0 100644 --- a/src/genmob.h +++ b/src/genmob.h @@ -31,8 +31,6 @@ int write_mobile_mobprog(mob_vnum mvnum, struct char_data *mob, FILE *fd); #endif /* Handy macros. */ -#define GET_NDD(mob) ((mob)->mob_specials.damnodice) -#define GET_SDD(mob) ((mob)->mob_specials.damsizedice) #define GET_ALIAS(mob) ((mob)->player.name) #define GET_SDESC(mob) ((mob)->player.short_descr) #define GET_LDESC(mob) ((mob)->player.long_descr) diff --git a/src/genolc.c b/src/genolc.c index 65d195b..7b24ffa 100644 --- a/src/genolc.c +++ b/src/genolc.c @@ -613,14 +613,14 @@ static int export_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd) ); fprintf(fd, "%d %d %d %d %d %d %d %d %d E\n" - "%d %dd%d+%d %dd%d\n", + "%d %dd%d+%d\n", MOB_FLAGS(mob)[0], MOB_FLAGS(mob)[1], MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3], AFF_FLAGS(mob)[0], AFF_FLAGS(mob)[1], AFF_FLAGS(mob)[2], AFF_FLAGS(mob)[3], GET_ALIGNMENT(mob), GET_LEVEL(mob), GET_HIT(mob), - GET_MANA(mob), GET_MOVE(mob), GET_NDD(mob), GET_SDD(mob)); + GET_MANA(mob), GET_MOVE(mob)); fprintf(fd, "%d %d %d\n", GET_POS(mob), GET_DEFAULT_POS(mob), GET_SEX(mob) diff --git a/src/medit.c b/src/medit.c index ff84b68..6ffc84b 100644 --- a/src/medit.c +++ b/src/medit.c @@ -227,7 +227,6 @@ static void init_mobile(struct char_data *mob) GET_HIT(mob) = GET_MANA(mob) = 1; GET_MAX_MANA(mob) = GET_MAX_MOVE(mob) = 100; - GET_NDD(mob) = GET_SDD(mob) = 1; GET_WEIGHT(mob) = 200; GET_HEIGHT(mob) = 198; @@ -467,23 +466,26 @@ static void medit_disp_stats_menu(struct descriptor_data *d) clear_screen(d); /* Color codes have to be used here, for count_color_codes to work */ - sprintf(buf, "(range \ty%d\tn to \ty%d\tn)", GET_HIT(mob) + GET_MOVE(mob), (GET_HIT(mob) * GET_MANA(mob)) + GET_MOVE(mob)); + sprintf(buf, "(range \ty%d\tn to \ty%d\tn)", GET_HIT(mob) + GET_MOVE(mob), + (GET_HIT(mob) * GET_MANA(mob)) + GET_MOVE(mob)); /* Top section - standard stats */ write_to_output(d, "-- Mob Number: %s[%s%d%s]%s\r\n" "(%s1%s) Level: %s[%s%4d%s]%s\r\n" "(%s2%s) %sAuto Set Stats (based on level)%s\r\n\r\n" - "Hit Points (xdy+z): Bare Hand Damage (xdy+z): \r\n" - "(%s3%s) HP NumDice: %s[%s%5d%s]%s (%s6%s) BHD NumDice: %s[%s%5d%s]%s\r\n" - "(%s4%s) HP SizeDice: %s[%s%5d%s]%s (%s7%s) BHD SizeDice: %s[%s%5d%s]%s\r\n" - "(%s5%s) HP Addition: %s[%s%5d%s]%s (%s8%s) Alignment: %s[%s%5d%s]%s\r\n\r\n", + "Hit Points (xdy+z):\r\n" + "(%s3%s) HP NumDice: %s[%s%5d%s]%s\r\n" + "(%s4%s) HP SizeDice: %s[%s%5d%s]%s\r\n" + "(%s5%s) HP Addition: %s[%s%5d%s]%s\r\n" + "(%s8%s) Alignment: %s[%s%5d%s]%s\r\n\r\n", cyn, yel, OLC_NUM(d), cyn, nrm, cyn, nrm, cyn, yel, GET_LEVEL(mob), cyn, nrm, cyn, nrm, cyn, nrm, - cyn, nrm, cyn, yel, GET_HIT(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_NDD(mob), cyn, nrm, - cyn, nrm, cyn, yel, GET_MANA(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_SDD(mob), cyn, nrm, - cyn, nrm, cyn, yel, GET_MOVE(mob), cyn, nrm, cyn, nrm, cyn, yel, GET_ALIGNMENT(mob), cyn, nrm + cyn, nrm, cyn, yel, GET_HIT(mob), cyn, nrm, + cyn, nrm, cyn, yel, GET_MANA(mob), cyn, nrm, + cyn, nrm, cyn, yel, GET_MOVE(mob), cyn, nrm, + cyn, nrm, cyn, yel, GET_ALIGNMENT(mob), cyn, nrm ); if (CONFIG_MEDIT_ADVANCED) { @@ -690,14 +692,6 @@ void medit_parse(struct descriptor_data *d, char *arg) OLC_MODE(d) = MEDIT_ADD_HP; i++; break; - case '6': - OLC_MODE(d) = MEDIT_NDD; - i++; - break; - case '7': - OLC_MODE(d) = MEDIT_SDD; - i++; - break; case '8': OLC_MODE(d) = MEDIT_ALIGNMENT; i++; @@ -908,18 +902,6 @@ void medit_parse(struct descriptor_data *d, char *arg) GET_SEX(OLC_MOB(d)) = LIMIT(i - 1, 0, NUM_GENDERS - 1); break; - case MEDIT_NDD: - GET_NDD(OLC_MOB(d)) = LIMIT(i, 0, 30); - OLC_VAL(d) = TRUE; - medit_disp_stats_menu(d); - return; - - case MEDIT_SDD: - GET_SDD(OLC_MOB(d)) = LIMIT(i, 0, 127); - OLC_VAL(d) = TRUE; - medit_disp_stats_menu(d); - return; - case MEDIT_NUM_HP_DICE: GET_HIT(OLC_MOB(d)) = LIMIT(i, 0, 30); OLC_VAL(d) = TRUE; @@ -1083,9 +1065,6 @@ void medit_autoroll_stats(struct descriptor_data *d) 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 */ - /* '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 */ diff --git a/src/oasis.h b/src/oasis.h index 26c9928..53881eb 100644 --- a/src/oasis.h +++ b/src/oasis.h @@ -252,43 +252,41 @@ extern const char *nrm, *grn, *cyn, *yel; #define ZEDIT_ZONE_CLAIM 26 /* Submodes of MEDIT connectedness. */ -#define MEDIT_MAIN_MENU 0 -#define MEDIT_KEYWORD 1 -#define MEDIT_S_DESC 2 -#define MEDIT_L_DESC 3 -#define MEDIT_D_DESC 4 -#define MEDIT_NPC_FLAGS 5 -#define MEDIT_AFF_FLAGS 6 -#define MEDIT_CONFIRM_SAVESTRING 7 -#define MEDIT_STATS_MENU 8 +#define MEDIT_MAIN_MENU 0 +#define MEDIT_KEYWORD 1 +#define MEDIT_S_DESC 2 +#define MEDIT_L_DESC 3 +#define MEDIT_D_DESC 4 +#define MEDIT_NPC_FLAGS 5 +#define MEDIT_AFF_FLAGS 6 +#define MEDIT_CONFIRM_SAVESTRING 7 +#define MEDIT_STATS_MENU 8 /* Numerical responses. */ #define MEDIT_NUMERICAL_RESPONSE 10 #define MEDIT_SEX 11 -#define MEDIT_NDD 12 -#define MEDIT_SDD 13 -#define MEDIT_NUM_HP_DICE 14 -#define MEDIT_SIZE_HP_DICE 15 -#define MEDIT_ADD_HP 16 -#define MEDIT_POS 17 -#define MEDIT_DEFAULT_POS 18 -#define MEDIT_ATTACK 19 -#define MEDIT_LEVEL 20 -#define MEDIT_ALIGNMENT 21 -#define MEDIT_DELETE 22 -#define MEDIT_COPY 23 -#define MEDIT_STR 24 -#define MEDIT_INT 25 -#define MEDIT_WIS 26 -#define MEDIT_DEX 27 -#define MEDIT_CON 28 -#define MEDIT_CHA 29 -#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 +#define MEDIT_NUM_HP_DICE 12 +#define MEDIT_SIZE_HP_DICE 13 +#define MEDIT_ADD_HP 14 +#define MEDIT_POS 15 +#define MEDIT_DEFAULT_POS 16 +#define MEDIT_ATTACK 17 +#define MEDIT_LEVEL 18 +#define MEDIT_ALIGNMENT 19 +#define MEDIT_DELETE 20 +#define MEDIT_COPY 21 +#define MEDIT_STR 22 +#define MEDIT_INT 23 +#define MEDIT_WIS 24 +#define MEDIT_DEX 25 +#define MEDIT_CON 26 +#define MEDIT_CHA 27 +#define MEDIT_SAVE_STR 28 +#define MEDIT_SAVE_DEX 29 +#define MEDIT_SAVE_CON 30 +#define MEDIT_SAVE_INT 31 +#define MEDIT_SAVE_WIS 32 +#define MEDIT_SAVE_CHA 33 /* Submodes of SEDIT connectedness. */ #define SEDIT_MAIN_MENU 0 diff --git a/src/structs.h b/src/structs.h index 89635a6..34c8f44 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1014,8 +1014,6 @@ struct mob_special_data memory_rec *memory; /**< List of PCs to remember */ byte attack_type; /**< The primary attack type (bite, sting, hit, etc.) */ byte default_pos; /**< Default position (standing, sleeping, etc.) */ - byte damnodice; /**< The number of dice to roll for damage */ - byte damsizedice; /**< The size of each die rolled for damage. */ }; /** An affect structure. */