diff --git a/lib/cfg/mob_classes.xml b/lib/cfg/mob_classes.xml
index 0b6aaf420..8eaf698de 100644
--- a/lib/cfg/mob_classes.xml
+++ b/lib/cfg/mob_classes.xml
@@ -57,6 +57,7 @@
+
@@ -153,6 +154,7 @@
+
@@ -249,6 +251,7 @@
+
@@ -345,6 +348,7 @@
+
@@ -441,6 +445,7 @@
+
@@ -537,6 +542,7 @@
+
@@ -634,6 +640,7 @@
+
@@ -729,6 +736,7 @@
+
@@ -825,6 +833,7 @@
+
@@ -921,6 +930,7 @@
+
diff --git a/lib/cfg/skills.xml b/lib/cfg/skills.xml
index 17e9df0fa..225da5a07 100644
--- a/lib/cfg/skills.xml
+++ b/lib/cfg/skills.xml
@@ -68,7 +68,7 @@ mode - режим умения.
-
+
diff --git a/src/gameplay/classes/mob_classes_info.cpp b/src/gameplay/classes/mob_classes_info.cpp
index 44153e109..2b3ab5b2f 100644
--- a/src/gameplay/classes/mob_classes_info.cpp
+++ b/src/gameplay/classes/mob_classes_info.cpp
@@ -317,6 +317,9 @@ void MobClassInfoBuilder::ParseCombatStatsData(ItemPtr &info, DataNode &node) {
} else if (id_str == "kHitroll") {
info->hitroll = data;
info->has_hitroll = true;
+ } else if (id_str == "kDamroll") {
+ info->damroll = data;
+ info->has_damroll = true;
} else if (id_str == "kMorale") {
info->morale = data;
info->has_morale = true;
@@ -636,6 +639,17 @@ void MobClassInfo::PrintCombatStatsTable(CharData *ch, std::ostringstream &buffe
<< table_wrapper::kEndRow;
}
+ if (has_damroll) {
+ table << "Damroll"
+ << damroll.base
+ << damroll.low_increment
+ << damroll.threshold_mort
+ << damroll.increment
+ << DeviationTypeToString(damroll.deviation_type)
+ << damroll.deviation
+ << table_wrapper::kEndRow;
+ }
+
if (has_morale) {
table << "Morale"
<< morale.base
diff --git a/src/gameplay/classes/mob_classes_info.h b/src/gameplay/classes/mob_classes_info.h
index 377ba7ef7..96a744742 100644
--- a/src/gameplay/classes/mob_classes_info.h
+++ b/src/gameplay/classes/mob_classes_info.h
@@ -81,17 +81,18 @@ class MobClassInfo : public info_container::BaseItem {
bool has_dam_n_dice{false};
bool has_dam_s_dice{false};
- // Hitroll / luck(morale) / cast success
+ // Hitroll / damroll / luck(morale) / cast success
ParametersData hitroll;
+ ParametersData damroll;
ParametersData morale;
ParametersData initiative;
ParametersData cast_success;
bool has_hitroll{false};
+ bool has_damroll{false};
bool has_morale{false};
bool has_initiative{false};
bool has_cast_success{false};
-
// HP / size / exp / likes_work
ParametersData hit_points;
ParametersData size;
diff --git a/src/gameplay/classes/recalc_mob_params_by_vnum.cpp b/src/gameplay/classes/recalc_mob_params_by_vnum.cpp
index 90aadf047..1837f8595 100644
--- a/src/gameplay/classes/recalc_mob_params_by_vnum.cpp
+++ b/src/gameplay/classes/recalc_mob_params_by_vnum.cpp
@@ -576,6 +576,22 @@ static bool ApplyMobParams(CharData* ch, int level, int remorts, int difficulty)
applied_any = 1;
}
+ if (info->has_damroll) {
+ p_data = &info->damroll;
+
+ int base_value = CalcBaseValue(p_data, calc, effective_remorts);
+ base_value = ApplyDeviation(p_data, base_value);
+
+ if (is_first_role_pass) {
+ GET_DR(ch) = base_value;
+ } else {
+ if (base_value > GET_DR(ch)) {
+ GET_DR(ch) = base_value;
+ }
+ }
+ applied_any = 1;
+ }
+
if (info->has_morale) {
p_data = &info->morale;
diff --git a/src/gameplay/skills/punctual_style.cpp b/src/gameplay/skills/punctual_style.cpp
index 45489c157..5663be3df 100644
--- a/src/gameplay/skills/punctual_style.cpp
+++ b/src/gameplay/skills/punctual_style.cpp
@@ -54,7 +54,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
return;
case 4: // Hit genus, victim bashed, speed/2
victim->battle_affects.set(kEafSlow);
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 10);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual) / 10), 20);
if (victim->GetPosition() > EPosition::kSit) {
victim->SetPosition(EPosition::kSit);
}
@@ -72,8 +72,8 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
to_char = "повалило $N3 на землю";
to_vict = "повредило вам колено, повалив на землю";
break;
- case 6: // foot damaged, speed/2
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 9);
+ case 6: // foot damaged, speed/2
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual) / 9), 23);
to_char = "замедлило движения $N1";
to_vict = "сломало вам лодыжку";
victim->battle_affects.set(kEafSlow);
@@ -83,7 +83,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
if (GET_EQ(victim, EEquipPos::kLegs))
DamageEquipment(victim, EEquipPos::kLegs, 100, 100);
else {
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 8);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual)) / 8, 25);
to_char = "замедлило движения $N1";
to_vict = "сломало вам ногу";
af[0].type = ESpell::kBattle;
@@ -92,7 +92,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
}
break;
case 8: // femor damaged, no speed
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 7);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual)) / 7, 29);
to_char = "сильно замедлило движения $N1";
to_vict = "сломало вам бедро";
af[0].type = ESpell::kBattle;
@@ -101,7 +101,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 10: // genus damaged, no speed, -2HR
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 7);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual)) / 7, 29);
to_char = "сильно замедлило движения $N1";
to_vict = "раздробило вам колено";
af[0].type = ESpell::kBattle;
@@ -111,7 +111,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 11: // femor damaged, no speed, no attack
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 7);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual)) / 7, 29);
to_char = "вывело $N3 из строя";
to_vict = "раздробило вам бедро";
af[0].type = ESpell::kBattle;
@@ -125,9 +125,9 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
break;
default: // femor damaged, no speed, no attack
if (hit_data.dam_critic > 12)
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 5);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
else
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 6);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
to_char = "вывело $N3 из строя";
to_vict = "изуродовало вам ногу";
af[0].type = ESpell::kBattle;
@@ -154,8 +154,8 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
to_vict = "сбило вам дыхание";
break;
- case 5: // abdomin damaged, waits 1, speed/2
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 8);
+ case 5: // abdomin damaged, waits 1, speed/2
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 8, 25);
SetWaitState(victim, 2 * kBattleRound);
to_char = "ранило $N3 в живот";
to_vict = "ранило вас в живот";
@@ -166,13 +166,13 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
if (GET_EQ(victim, EEquipPos::kWaist))
DamageEquipment(victim, EEquipPos::kWaist, 100, 100);
else
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 7);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual)) / 7, 29);
to_char = "повредило $N2 живот";
to_vict = "повредило вам живот";
break;
case 7:
case 8: // abdomin damage, speed/2, HR-2
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 6);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
to_char = "ранило $N3 в живот";
to_vict = "ранило вас в живот";
af[0].type = ESpell::kBattle;
@@ -182,7 +182,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 9: // armor damaged, abdomin damaged, speed/2, HR-2
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 5);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
DamageEquipment(victim, EEquipPos::kBody, 100, 100);
to_char = "ранило $N3 в живот";
to_vict = "ранило вас в живот";
@@ -194,7 +194,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 10: // abdomin damaged, no speed, no attack
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 4);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 4, 67);
to_char = "повредило $N2 живот";
to_vict = "повредило вам живот";
af[0].type = ESpell::kBattle;
@@ -207,7 +207,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 11: // abdomin damaged, no speed, no attack
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 3);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 3, 67);
to_char = "разорвало $N2 живот";
to_vict = "разорвало вам живот";
af[0].type = ESpell::kBattle;
@@ -220,7 +220,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
default: // abdomin damaged, hits = 0
- hit_data.dam *= ch->GetSkill(ESkill::kPunctual) / 2;
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 2, 100);
to_char = "размозжило $N2 живот";
to_vict = "размозжило вам живот";
ImposeHaemorrhage(victim, 60);
@@ -245,7 +245,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
to_vict = "повредило вам грудь, свалив вас с ног";
break;
case 5: // chest damaged, waits 1, speed/2
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 6);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
SetWaitState(victim, 2 * kBattleRound);
to_char = "повредило $N2 туловище";
to_vict = "повредило вам туловище";
@@ -255,7 +255,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
break;
case 6: // shield damaged, chest damaged, speed/2
DamageEquipment(victim, EEquipPos::kShield, 100, 100);
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 6);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
to_char = "повредило $N2 туловище";
to_vict = "повредило вам туловище";
af[0].type = ESpell::kBattle;
@@ -264,7 +264,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
break;
case 7: // srmor damaged, chest damaged, speed/2, HR-2
DamageEquipment(victim, EEquipPos::kBody, 100, 100);
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 5);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
to_char = "повредило $N2 туловище";
to_vict = "повредило вам туловище";
af[0].type = ESpell::kBattle;
@@ -274,7 +274,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 8: // chest damaged, no speed, no attack
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 5);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
to_char = "вывело $N3 из строя";
to_vict = "повредило вам туловище";
af[0].type = ESpell::kBattle;
@@ -287,7 +287,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 9: // chest damaged, speed/2, HR-2
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 4);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 4, 67);
to_char = "заставило $N3 ослабить натиск";
to_vict = "сломало вам ребра";
af[0].type = ESpell::kBattle;
@@ -299,7 +299,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
victim->battle_affects.set(kEafSlow);
break;
case 10: // chest damaged, no speed, no attack
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 4);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 4, 67);
to_char = "вывело $N3 из строя";
to_vict = "сломало вам ребра";
af[0].type = ESpell::kBattle;
@@ -316,7 +316,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
af[0].bitvector = to_underlying(EAffect::kStopFight);
af[0].duration = CalcDuration(victim, 8, 0, 0, 0, 0);
af[0].battleflag = kAfBattledec | kAfPulsedec;
- hit_data.dam *= ch->GetSkill(ESkill::kPunctual) / 2;
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 2, 100);
ImposeHaemorrhage(victim, 50);
to_char = "вывело $N3 из строя";
to_vict = "разорвало вам грудь";
@@ -326,7 +326,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
af[0].bitvector = to_underlying(EAffect::kStopFight);
af[0].duration = CalcDuration(victim, 8, 0, 0, 0, 0);
af[0].battleflag = kAfBattledec | kAfPulsedec;
- hit_data.dam *= ch->GetSkill(ESkill::kPunctual) / 2;
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 2, 100);
ImposeHaemorrhage(victim, 60);
to_char = "вывело $N3 из строя";
to_vict = "размозжило вам грудь";
@@ -379,14 +379,14 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
else
DamageEquipment(victim, EEquipPos::kHands, 100, 100);
if (!GET_EQ(victim, EEquipPos::kArms) && !GET_EQ(victim, EEquipPos::kHands))
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 7);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual)) / 7, 29);
to_char = "ослабило атаку $N1";
to_vict = "повредило вам руку";
break;
case 8: // shield damaged, hands damaged, waits 1
DamageEquipment(victim, EEquipPos::kShield, 100, 100);
SetWaitState(victim, 2 * kBattleRound);
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 7);
+ hit_data.dam *= std::min((ch->GetSkill(ESkill::kPunctual)) / 7, 29);
to_char = "придержало $N3";
to_vict = "повредило вам руку";
break;
@@ -398,7 +398,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
unequip_pos = EEquipPos::kWield;
else if (GET_EQ(victim, EEquipPos::kHold))
unequip_pos = EEquipPos::kHold;
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 6);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
to_char = "придержало $N3";
to_vict = "повредило вам руку";
break;
@@ -454,7 +454,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
af[1].bitvector = to_underlying(EAffect::kNoFlee);
ImposeHaemorrhage(victim, 30);
if (hit_data.dam_critic >= 13)
- hit_data.dam *= ch->GetSkill(ESkill::kPunctual) / 5;
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 5, 40);
victim->battle_affects.set(kEafSlow);
break;
}
@@ -481,7 +481,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
af[0].location = EApply::kHitroll;
af[0].modifier = -2;
}
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 4);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 4, 67);
to_char = "повредило $N2 голову";
to_vict = "повредило вам голову";
break;
@@ -489,7 +489,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
af[0].type = ESpell::kBattle;
af[0].location = EApply::kHitroll;
af[0].modifier = -2;
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 4);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 4, 67);
to_char = "повредило $N2 голову";
to_vict = "повредило вам голову";
break;
@@ -507,7 +507,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
SetWaitState(victim, 4 * kBattleRound);
DamageEquipment(victim, EEquipPos::kHead, 100, 100);
//dam = GET_HIT(victim);
- hit_data.dam *= ch->GetSkill(ESkill::kPunctual) / 2;
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 2, 100);
to_char = "отбило у $N1 сознание";
to_vict = "отбило у вас сознание";
ImposeHaemorrhage(victim, 20);
@@ -518,12 +518,12 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
af[0].duration = CalcDuration(victim, 8, 0, 0, 0, 0);
af[0].battleflag = kAfBattledec | kAfPulsedec;
ImposeHaemorrhage(victim, 30);
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 3);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 3, 67);
to_char = "повергло $N3 в оцепенение";
to_vict = "повергло вас в оцепенение";
break;
case 10: // head damaged, -1 INT/WIS/CHA
- hit_data.dam *= (ch->GetSkill(ESkill::kPunctual) / 2);
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 2, 100);
af[0].type = ESpell::kBattle;
af[0].location = EApply::kInt;
af[0].modifier = -1;
@@ -548,7 +548,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
to_vict = "сорвало у вас крышу";
break;
case 11: // hits 0, WIS/2, INT/2, CHA/2
- hit_data.dam *= ch->GetSkill(ESkill::kPunctual) / 2;
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 2, 100);
af[0].type = ESpell::kBattle;
af[0].location = EApply::kInt;
af[0].modifier = -victim->get_int() / 2;
@@ -584,7 +584,7 @@ void PerformPunctualHit(CharData *ch, CharData *victim, HitData &hit_data) {
af[2].modifier = -victim->get_cha() / 2;
af[2].duration = CalcDuration(victim, number(1, 6) * 24, 0, 0, 0, 0);
af[2].battleflag = kAfDeadkeep;
- hit_data.dam *= ch->GetSkill(ESkill::kPunctual) / 2;
+ hit_data.dam *= std::min(ch->GetSkill(ESkill::kPunctual) / 2, 100);
to_char = "размозжило $N2 голову";
to_vict = "размозжило вам голову";
ImposeHaemorrhage(victim, 90);