mirror of
https://github.com/Corfirean/coa-server-manager.git
synced 2026-11-12 20:11:02 +00:00
Content Scaling module settings: creature health multipliers
Five float fields (open world, dungeons, raids, ordinary mobs, bosses; 0.1 to 10) in six languages, with save-time validation in coa-core. They appear once the server's Content Scaling module carries the matching CoAContentScaling.Difficulty.Health.* settings. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
19791edb94
commit
f6eccf849f
3 files changed
+48
No files matched your search
@@ -0,0 +1,7 @@
|
||||
---
|
||||
area: manager
|
||||
type: added
|
||||
audience: admins
|
||||
title: Module settings for Content Scaling include creature health
|
||||
---
|
||||
The Content Scaling page now has five health multipliers: for the open world, dungeons and raids, and for ordinary mobs and bosses. They multiply the health the scaling already gives creatures (1 keeps the normal balance, lower is easier, 0.1 to 10) and need a server build that includes the matching Content Scaling settings.
|
||||
@@ -371,6 +371,12 @@ fn save_settings_in(cat: &[Entry], root: &Path, meta: &Path, id: &str, changes:
|
||||
return Err(Error::Invalid("Enemy damage must be a number from 0.25 to 2.0.".into()));
|
||||
}
|
||||
}
|
||||
if id == "content-scaling" && key.starts_with("CoAContentScaling.Difficulty.Health.") && key.ends_with("Multiplier") {
|
||||
let multiplier = value.parse::<f32>().map_err(|_| Error::Invalid("Health multipliers must be a number from 0.1 to 10.".into()))?;
|
||||
if !multiplier.is_finite() || !(0.1..=10.0).contains(&multiplier) {
|
||||
return Err(Error::Invalid("Health multipliers must be a number from 0.1 to 10.".into()));
|
||||
}
|
||||
}
|
||||
if id == "content-scaling" && key == "CoAContentScaling.World.Leech.Percent" {
|
||||
let percent = value.parse::<f32>().map_err(|_| Error::Invalid("Life steal must be a number from 0 to 100 percent.".into()))?;
|
||||
if !percent.is_finite() || !(0.0..=100.0).contains(&percent) {
|
||||
@@ -697,6 +703,36 @@ mod tests {
|
||||
assert_eq!(settings_in(&cat, &root, "content-scaling").unwrap().iter().find(|s| s.key == key).unwrap().value, "2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creature_health_multipliers_are_validated_per_key() {
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
let (root, meta) = server(d.path());
|
||||
let cat = catalog();
|
||||
let conf = dir(&root).join("mod-coa-content-scaling.conf.dist");
|
||||
let keys = [
|
||||
"CoAContentScaling.Difficulty.Health.WorldMultiplier",
|
||||
"CoAContentScaling.Difficulty.Health.DungeonMultiplier",
|
||||
"CoAContentScaling.Difficulty.Health.RaidMultiplier",
|
||||
"CoAContentScaling.Difficulty.Health.TrashMultiplier",
|
||||
"CoAContentScaling.Difficulty.Health.BossMultiplier",
|
||||
];
|
||||
let mut text = String::from("CoAContentScaling.Enable = 1\n");
|
||||
for key in keys {
|
||||
text.push_str(&format!("{key} = 1.0\n"));
|
||||
}
|
||||
fs::write(&conf, text).unwrap();
|
||||
for key in keys {
|
||||
let changes = |v: &str| BTreeMap::from([(key.to_string(), v.to_string())]);
|
||||
for bad in ["NaN", "inf", "0", "0.09", "10.01", "-1", "abc", ""] {
|
||||
assert!(save_settings_in(&cat, &root, &meta, "content-scaling", &changes(bad)).is_err(), "{key} {bad}");
|
||||
}
|
||||
for good in ["0.1", "0.4", "1", "2.5", "10"] {
|
||||
assert_eq!(save_settings_in(&cat, &root, &meta, "content-scaling", &changes(good)).unwrap(), [key]);
|
||||
assert_eq!(settings_in(&cat, &root, "content-scaling").unwrap().iter().find(|s| s.key == key).unwrap().value, good);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_older_file_name_is_used_when_the_current_one_is_missing_and_a_part_that_cannot_be_switched_stays_on() {
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
|
||||
@@ -50,6 +50,11 @@ add(scaling + "LFG.AllowPartialGroups", "bool", ["Enter with the current party",
|
||||
add(scaling + "World.Leech.Enable", "bool", ["Open-world life steal", "Отхил от урона в открытом мире", "Lebensraub in der offenen Welt", "Vol de vie en monde ouvert", "Robo de vida en mundo abierto", "开放世界吸血"], ["Heal from your damage to open-world creatures. Excludes players, their pets and instances. Requires the module; group scaling and solo assistance are optional.", "Восстанавливает здоровье от вашего урона существам открытого мира. Исключает игроков, их питомцев и инстансы. Требует включения модуля; скейлинг группы и соло-помощь необязательны.", "Heilt durch eigenen Schaden an Weltkreaturen. Ohne Spieler, deren Begleiter und Instanzen. Erfordert das Modul; Gruppenanpassung und Solohilfe sind optional.", "Soigne grâce aux dégâts aux créatures du monde ouvert. Exclut joueurs, familiers et instances. Nécessite le module ; adaptation au groupe et aide solo facultatives.", "Cura con tu daño a criaturas del mundo abierto. Excluye jugadores, mascotas e instancias. Requiere el módulo; ajuste al grupo y ayuda individual opcionales.", "对开放世界生物造成伤害时恢复生命。不适用于玩家、玩家宠物和副本。需要启用模块,队伍缩放和单人辅助可选。"]);
|
||||
add(scaling + "World.Leech.Percent", "float", ["Life steal (%)", "Отхил от нанесённого урона (%)", "Lebensraub (%)", "Vol de vie (%)", "Robo de vida (%)", "吸血比例(%)"], ["Percentage of damage returned as health: 0–100. 10 means 10%. Requires open-world life steal. Overkill gives no extra healing.", "Процент урона, возвращаемый здоровьем: 0–100. Значение 10 означает 10%. Требует включения отхила в открытом мире. Избыточный урон при добивании не увеличивает отхил.", "Schadensanteil als Heilung: 0–100. 10 bedeutet 10%. Erfordert Welt-Lebensraub. Überzähliger Schaden heilt nicht zusätzlich.", "Pourcentage des dégâts rendu en vie : 0–100. 10 signifie 10%. Nécessite le vol de vie. Les dégâts excédentaires ne soignent pas davantage.", "Porcentaje del daño recuperado como salud: 0–100. 10 significa 10%. Requiere robo de vida. El daño excedente no aporta curación adicional.", "将伤害的0至100%转化为生命。10表示10%。需要启用吸血。过量伤害不会额外治疗。"], { min: 0, max: 100 });
|
||||
add(scaling + "Difficulty.DamageMultiplier", "range", ["Enemy damage", "Урон противников", "Gegnerschaden", "Dégâts ennemis", "Daño enemigo", "敌人伤害"], ["Dungeon and raid damage after group scaling and solo assistance. 100% keeps the normal balance; lower is easier. Applies to everyone on this server. Does not change health, loot or instant-kill mechanics.", "Урон в подземельях и рейдах после скейлинга группы и соло-помощи. 100% — обычный баланс, ниже — легче. Действует для всех игроков сервера. Не меняет здоровье, добычу и механики мгновенной смерти.", "Schaden in Dungeons und Schlachtzügen nach Gruppenanpassung und Solohilfe. 100% ist normal, weniger ist leichter. Gilt für alle Spieler. Ändert weder Gesundheit noch Beute oder Soforttötungen.", "Dégâts en donjon et raid après adaptation au groupe et aide solo. 100% conserve l’équilibrage normal ; moins est plus facile. Pour tous les joueurs. Ne change ni la vie, ni le butin, ni les morts instantanées.", "Daño en mazmorras y bandas tras el ajuste del grupo y la ayuda individual. 100% mantiene el equilibrio normal; menos es más fácil. Para todos los jugadores. No cambia salud, botín ni muerte instantánea.", "队伍缩放和单人辅助后的地下城与团队副本伤害。100%为正常,降低后更容易。对全服玩家生效,不改变生命值、掉落或即死机制。"], { min: 0.25, max: 2 });
|
||||
add(scaling + "Difficulty.Health.WorldMultiplier", "float", ["Mob health in the open world (×)", "Здоровье мобов в открытом мире (×)", "Mob-Gesundheit in der offenen Welt (×)", "Vie des monstres en monde ouvert (×)", "Vida de los monstruos en el mundo abierto (×)", "野外怪物生命值(×)"], ["Multiplies the health of scaled creatures in the open world, on top of the scaling and the world health setting of the server. 1 keeps the normal balance; lower is easier. Creatures already in the world change when they respawn.", "Умножает здоровье подстроенных существ в открытом мире поверх скейлинга и настройки здоровья мира. 1 — обычный баланс, меньше — легче. Существа, уже стоящие в мире, меняются после возрождения.", "Multipliziert die Gesundheit skalierter Kreaturen in der offenen Welt zusätzlich zur Skalierung und zur Welt-Gesundheitseinstellung. 1 ist normal, weniger ist leichter. Bereits vorhandene Kreaturen ändern sich nach dem Respawn.", "Multiplie la vie des créatures adaptées en monde ouvert, en plus de l’adaptation et du réglage de vie du monde. 1 conserve l’équilibrage normal ; moins est plus facile. Les créatures déjà présentes changent après réapparition.", "Multiplica la vida de las criaturas ajustadas en el mundo abierto, además del ajuste y la vida configurada del mundo. 1 mantiene el equilibrio normal; menos es más fácil. Las criaturas ya presentes cambian al reaparecer.", "在缩放和服务器世界生命值设置之上,倍乘野外已缩放生物的生命值。1为正常,降低后更容易。已存在的生物在重生后生效。"], { min: 0.1, max: 10 });
|
||||
add(scaling + "Difficulty.Health.DungeonMultiplier", "float", ["Mob health in dungeons (×)", "Здоровье мобов в подземельях (×)", "Mob-Gesundheit in Dungeons (×)", "Vie des monstres en donjon (×)", "Vida de los monstruos en mazmorras (×)", "地下城怪物生命值(×)"], ["Multiplies the health of scaled creatures in dungeons, on top of the scaling and the dungeon health setting of the server. 1 keeps the normal balance; lower is easier. Applies to new dungeon runs.", "Умножает здоровье подстроенных существ в подземельях поверх скейлинга и настройки здоровья подземелий. 1 — обычный баланс, меньше — легче. Действует на новые заходы.", "Multipliziert die Gesundheit skalierter Kreaturen in Dungeons zusätzlich zur Skalierung und zur Dungeon-Gesundheitseinstellung. 1 ist normal, weniger ist leichter. Gilt für neue Dungeon-Läufe.", "Multiplie la vie des créatures adaptées en donjon, en plus de l’adaptation et du réglage de vie des donjons. 1 conserve l’équilibrage normal ; moins est plus facile. S’applique aux nouvelles instances.", "Multiplica la vida de las criaturas ajustadas en mazmorras, además del ajuste y la vida configurada de mazmorras. 1 mantiene el equilibrio normal; menos es más fácil. Se aplica a nuevas instancias.", "在缩放和服务器地下城生命值设置之上,倍乘地下城内已缩放生物的生命值。1为正常,降低后更容易。对新的副本生效。"], { min: 0.1, max: 10 });
|
||||
add(scaling + "Difficulty.Health.RaidMultiplier", "float", ["Mob health in raids (×)", "Здоровье мобов в рейдах (×)", "Mob-Gesundheit in Schlachtzügen (×)", "Vie des monstres en raid (×)", "Vida de los monstruos en bandas (×)", "团队副本怪物生命值(×)"], ["Multiplies the health of scaled creatures in raids, on top of the scaling and the raid health setting of the server. 1 keeps the normal balance; lower is easier. A boss with a calibrated health value keeps it.", "Умножает здоровье подстроенных существ в рейдах поверх скейлинга и настройки здоровья рейдов. 1 — обычный баланс, меньше — легче. Босс с откалиброванным здоровьем сохраняет его.", "Multipliziert die Gesundheit skalierter Kreaturen in Schlachtzügen zusätzlich zur Skalierung und zur Schlachtzug-Gesundheitseinstellung. 1 ist normal, weniger ist leichter. Ein Boss mit kalibriertem Wert behält ihn.", "Multiplie la vie des créatures adaptées en raid, en plus de l’adaptation et du réglage de vie des raids. 1 conserve l’équilibrage normal ; moins est plus facile. Un boss à vie calibrée la conserve.", "Multiplica la vida de las criaturas ajustadas en bandas, además del ajuste y la vida configurada de bandas. 1 mantiene el equilibrio normal; menos es más fácil. Un jefe con vida calibrada la conserva.", "在缩放和服务器团队副本生命值设置之上,倍乘团队副本内已缩放生物的生命值。1为正常,降低后更容易。有校准生命值的首领保持原值。"], { min: 0.1, max: 10 });
|
||||
add(scaling + "Difficulty.Health.TrashMultiplier", "float", ["Ordinary mob health (×)", "Здоровье обычных мобов (×)", "Gesundheit gewöhnlicher Mobs (×)", "Vie des monstres ordinaires (×)", "Vida de monstruos normales (×)", "普通怪物生命值(×)"], ["Multiplies the health of ordinary creatures everywhere, together with the place setting. 1 keeps the normal balance; lower is easier.", "Умножает здоровье обычных существ везде, вместе с настройкой места. 1 — обычный баланс, меньше — легче.", "Multipliziert die Gesundheit gewöhnlicher Kreaturen überall, zusammen mit der Ortseinstellung. 1 ist normal, weniger ist leichter.", "Multiplie la vie des créatures ordinaires partout, avec le réglage du lieu. 1 conserve l’équilibrage normal ; moins est plus facile.", "Multiplica la vida de las criaturas normales en todas partes, junto con el ajuste del lugar. 1 mantiene el equilibrio normal; menos es más fácil.", "与所在区域设置一起,倍乘各处普通生物的生命值。1为正常,降低后更容易。"], { min: 0.1, max: 10 });
|
||||
add(scaling + "Difficulty.Health.BossMultiplier", "float", ["Boss health (×)", "Здоровье боссов (×)", "Boss-Gesundheit (×)", "Vie des boss (×)", "Vida de los jefes (×)", "首领生命值(×)"], ["Multiplies the health of bosses everywhere, together with the place setting: a dungeon boss gets the dungeon and the boss multiplier. 1 keeps the normal balance; lower is easier.", "Умножает здоровье боссов везде, вместе с настройкой места: босс подземелья получает множитель подземелья и боссов. 1 — обычный баланс, меньше — легче.", "Multipliziert die Gesundheit von Bossen überall, zusammen mit der Ortseinstellung: ein Dungeon-Boss erhält den Dungeon- und den Boss-Multiplikator. 1 ist normal, weniger ist leichter.", "Multiplie la vie des boss partout, avec le réglage du lieu : un boss de donjon reçoit le multiplicateur du donjon et celui des boss. 1 conserve l’équilibrage normal ; moins est plus facile.", "Multiplica la vida de los jefes en todas partes, junto con el ajuste del lugar: un jefe de mazmorra recibe el multiplicador de mazmorra y el de jefes. 1 mantiene el equilibrio normal; menos es más fácil.", "与所在区域设置一起,倍乘各处首领的生命值:地下城首领同时受地下城和首领倍率影响。1为正常,降低后更容易。"], { min: 0.1, max: 10 });
|
||||
add(scaling + "SoloAssist.Mode", "enum", ["Solo assistance", "Помощь в соло", "Solohilfe", "Aide solo", "Ayuda individual", "单人辅助"], ["Additional damage reduction when the scaling target is one player.", "Дополнительное снижение урона, когда расчёт сложности рассчитан на одного игрока.", "Zusätzliche Schadensreduktion bei einem Skalierungsziel von einem Spieler.", "Réduction supplémentaire quand la difficulté est calculée pour un joueur.", "Reducción adicional cuando la dificultad se calcula para un jugador.", "难度目标为一名玩家时额外减伤。"], { options: [
|
||||
{ value: "None", label: ["None", "Без помощи", "Keine", "Aucune", "Ninguna", "无"] },
|
||||
{ value: "Light", label: ["Light (−15%)", "Лёгкая (−15%)", "Leicht (−15%)", "Légère (−15%)", "Ligera (−15%)", "轻度(−15%)"] },
|
||||
|
||||
Reference in new issue
Block a user