Remove bare hand damage in favor of unarmed skill proficiency

This commit is contained in:
kinther 2025-10-18 06:38:15 -07:00
parent 3fd48b60f6
commit cc342ef45c
10 changed files with 138 additions and 121 deletions

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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.

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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 */

View file

@ -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

View file

@ -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. */