mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'socksonme/rework_sct' into 'master'
Rework SCT See merge request veloren/veloren!3126
This commit is contained in:
commit
0bd08b1f9e
11
CHANGELOG.md
11
CHANGELOG.md
@ -31,6 +31,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Chest sprites can longer be exploded
|
||||
- Smoke varies by temperature, humidity, time of day and house
|
||||
- Added loot ownership for drops from mining
|
||||
- Added an option for experience number accumulation.
|
||||
- Added an option for damage number rounding (when greater than or equal to 1.0).
|
||||
- Added sliders for incoming/non-incoming damage accumulation duration.
|
||||
|
||||
### Changed
|
||||
|
||||
@ -43,8 +46,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Zoom-in effect when aiming bow is now optional
|
||||
- Non-Humanoid NPCs now pick up consumables when less than full health and use them to heal up.
|
||||
- Changed module component modifier costs to the following scheme, based on base material: 1 -> 2 -> 5 -> 10 -> 15 -> 25
|
||||
- Damage from the same source dealt in the same tick will now be grouped up.
|
||||
- Critical hits are now shown differently in the damage numbers.
|
||||
- Fall damage and some (extra) buffs/debuffs now show up in the damage numbers.
|
||||
|
||||
### Removed
|
||||
- Removed the options for single and cumulated damage.
|
||||
|
||||
### Fixed
|
||||
- Fixed bug that would sometimes cause taking a screenshot to panic because a buffer was mapped at the wrong time.
|
||||
@ -57,7 +64,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Fix villagers seeing cultists and familiar enemies through objects.
|
||||
- Menacing agents are now less spammy with their menacing messages
|
||||
- Fixed the title screen FPS cap not applying when the background FPS limit was set higher than 60 FPS
|
||||
|
||||
- Fixed an issue where the hurt animation would "jump" whenever you lost/gained health.
|
||||
- Fixed a bug where multiple damage sources in the same tick would show up as a singular attack.
|
||||
- Fixed an issue where, if the same amount of healing and damage was received in the same tick, nothing would be shown.
|
||||
## [0.12.0] - 2022-02-19
|
||||
|
||||
### Added
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Статусныя эфекты каля мінімапы",
|
||||
"hud.settings.toggle_bar_experience": "Адлюстроўваць панэль досведу",
|
||||
"hud.settings.scrolling_combat_text": "Адлюстроўваць шкоду/злечванне",
|
||||
"hud.settings.single_damage_number": "Шкода ад кожнага ўдару",
|
||||
"hud.settings.cumulated_damage": "Сумарная шкода",
|
||||
"hud.settings.incoming_damage": "Шкода ад кожнага ўдара па гульцу",
|
||||
"hud.settings.cumulated_incoming_damage": "Сумарная шкода па гульцу",
|
||||
"hud.settings.speech_bubble": "Індыкатар гаворкі",
|
||||
"hud.settings.speech_bubble_self": "Паказваць свае індыкатары гаворкі",
|
||||
"hud.settings.speech_bubble_dark_mode": "Цёмны рэжым індыкатара гаворкі",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Buffs al Minimapa",
|
||||
"hud.settings.toggle_bar_experience": "Mostra Barra d'Experiència",
|
||||
"hud.settings.scrolling_combat_text": "Text de Combat Desplaçat",
|
||||
"hud.settings.single_damage_number": "Danys en Nombres Rodons",
|
||||
"hud.settings.cumulated_damage": "Dany Acumulat",
|
||||
"hud.settings.incoming_damage": "Dany Imminent",
|
||||
"hud.settings.cumulated_incoming_damage": "Dany Imminent Acumulat",
|
||||
"hud.settings.speech_bubble": "Bafarades",
|
||||
"hud.settings.speech_bubble_self": "Mostrar les Bafarades pròpies",
|
||||
"hud.settings.speech_bubble_dark_mode": "Bafarades Mode Fosc",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Buffy u Minimapy",
|
||||
"hud.settings.toggle_bar_experience": "Povolit Zkušenostní Bar",
|
||||
"hud.settings.scrolling_combat_text": "Létajíci Text v boji",
|
||||
"hud.settings.single_damage_number": "Jednotná čísla Poškození",
|
||||
"hud.settings.cumulated_damage": "Seskupené Poškození",
|
||||
"hud.settings.incoming_damage": "Příchozí Poškození",
|
||||
"hud.settings.cumulated_incoming_damage": "Seskupené Příchozí Poškození",
|
||||
"hud.settings.speech_bubble": "Povídací Bublina",
|
||||
"hud.settings.speech_bubble_dark_mode": "Tmavá Povídací Bublina",
|
||||
"hud.settings.speech_bubble_icon": "Ikona Povídací Bubliny",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Effekte an der Minimap",
|
||||
"hud.settings.toggle_bar_experience": "Erfahrungsleiste umschalten",
|
||||
"hud.settings.scrolling_combat_text": "Fließtext für Kampfhandlungen",
|
||||
"hud.settings.single_damage_number": "Schaden einzeln anzeigen",
|
||||
"hud.settings.cumulated_damage": "Gesamtschaden anzeigen",
|
||||
"hud.settings.incoming_damage": "Erlittener Schaden",
|
||||
"hud.settings.cumulated_incoming_damage": "Gesamter erlittener Schaden",
|
||||
"hud.settings.speech_bubble": "Sprechblase",
|
||||
"hud.settings.speech_bubble_dark_mode": "Sprechblase: Nachtmodus",
|
||||
"hud.settings.speech_bubble_icon": "Sprechblasen-Icon",
|
||||
|
@ -25,16 +25,18 @@
|
||||
"hud.settings.buffs_mmap": "Buffs at Minimap",
|
||||
"hud.settings.toggle_bar_experience": "Toggle Experience Bar",
|
||||
"hud.settings.scrolling_combat_text": "Scrolling Combat Text",
|
||||
"hud.settings.single_damage_number": "Single Damage Numbers",
|
||||
"hud.settings.cumulated_damage": "Cumulated Damage",
|
||||
"hud.settings.damage_accumulation_duration": "Damage Accumulation Duration",
|
||||
"hud.settings.incoming_damage": "Incoming Damage",
|
||||
"hud.settings.cumulated_incoming_damage": "Cumulated Incoming Damage",
|
||||
"hud.settings.incoming_damage_accumulation_duration": "Incoming Damage Accumulation Duration",
|
||||
"hud.settings.round_damage": "Round Damage",
|
||||
"hud.settings.speech_bubble": "Speech Bubble",
|
||||
"hud.settings.speech_bubble_self": "Show Own Speech Bubbles",
|
||||
"hud.settings.speech_bubble_dark_mode": "Speech Bubble Dark Mode",
|
||||
"hud.settings.speech_bubble_icon": "Speech Bubble Icon",
|
||||
"hud.settings.energybar_numbers": "Energybar Numbers",
|
||||
"hud.settings.always_show_bars": "Always show Energybars",
|
||||
"hud.settings.experience_numbers": "Experience Numbers",
|
||||
"hud.settings.accumulate_experience": "Accumulate Experience Numbers",
|
||||
"hud.settings.values": "Values",
|
||||
"hud.settings.percentages": "Percentages",
|
||||
"hud.settings.chat": "Chat",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Estados en el Minimapa",
|
||||
"hud.settings.toggle_bar_experience": "Alternar Barra de Experiencia",
|
||||
"hud.settings.scrolling_combat_text": "Texto de Combate Deslizante",
|
||||
"hud.settings.single_damage_number": "Números de Daño Único",
|
||||
"hud.settings.cumulated_damage": "Daño Acumulado",
|
||||
"hud.settings.incoming_damage": "Daño Entrante",
|
||||
"hud.settings.cumulated_incoming_damage": "Daño Entrante Acumulado",
|
||||
"hud.settings.speech_bubble": "Burbuja de Diálogo",
|
||||
"hud.settings.speech_bubble_self": "Mostrar Diálogos propios en Burbuja",
|
||||
"hud.settings.speech_bubble_dark_mode": "Modo Oscuro de Burbuja de Diálogo",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Buffs en el Minimapa",
|
||||
"hud.settings.toggle_bar_experience": "Alternar Barra de Experiencia",
|
||||
"hud.settings.scrolling_combat_text": "Texto de Combate con Desplazamiento",
|
||||
"hud.settings.single_damage_number": "Números de Daño Singular",
|
||||
"hud.settings.cumulated_damage": "Daño Acumulado",
|
||||
"hud.settings.incoming_damage": "Daño Recibido",
|
||||
"hud.settings.cumulated_incoming_damage": "Daño Recibido Acumulado",
|
||||
"hud.settings.speech_bubble": "Burbuja de Diálogo",
|
||||
"hud.settings.speech_bubble_self": "Mostrar Diálogos propios en Burbuja",
|
||||
"hud.settings.speech_bubble_dark_mode": "Burbuja de Diálogo en Modo Oscuro",
|
||||
|
@ -18,10 +18,7 @@
|
||||
"hud.settings.opacity": "Opakotasuna",
|
||||
"hud.settings.toggle_shortcuts": "Aldatu laster teklak",
|
||||
"hud.settings.toggle_bar_experience": "Erakutsi/ezkutatu esperientzia barra",
|
||||
"hud.settings.single_damage_number": "Egindako kaltea banaka erakutsi",
|
||||
"hud.settings.cumulated_damage": "Egindako kaltea metatuta erakutsi",
|
||||
"hud.settings.incoming_damage": "Jasotako kaltea banaka erakutsi",
|
||||
"hud.settings.cumulated_incoming_damage": "Jasotako kalte metatua erakutsi",
|
||||
"hud.settings.energybar_numbers": "Zenbakiak energia barran",
|
||||
"hud.settings.always_show_bars": "Erakutsi beti energia barra",
|
||||
"hud.settings.values": "Balioak",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Effets sur la minimap",
|
||||
"hud.settings.toggle_bar_experience": "Activer la barre d'expérience",
|
||||
"hud.settings.scrolling_combat_text": "Dégats de combat",
|
||||
"hud.settings.single_damage_number": "Dégats infligés",
|
||||
"hud.settings.cumulated_damage": "Dégat infligés cumulés",
|
||||
"hud.settings.incoming_damage": "Dégats reçus",
|
||||
"hud.settings.cumulated_incoming_damage": "Dégats reçus cumulés",
|
||||
"hud.settings.speech_bubble": "Bulle de dialogue",
|
||||
"hud.settings.speech_bubble_self": "Montrer ses propres bulles de dialogue",
|
||||
"hud.settings.speech_bubble_dark_mode": "Bulle de dialogue Mode Sombre",
|
||||
|
@ -24,10 +24,7 @@
|
||||
"hud.settings.buffs_mmap": "Hatások a minitérképnél",
|
||||
"hud.settings.toggle_bar_experience": "Tapasztalatsáv megjelenítése/elrejtése",
|
||||
"hud.settings.scrolling_combat_text": "Harci szöveg görgetése",
|
||||
"hud.settings.single_damage_number": "Minden egyes sebzés",
|
||||
"hud.settings.cumulated_damage": "Összes sebzés",
|
||||
"hud.settings.incoming_damage": "Bejövő sebzés",
|
||||
"hud.settings.cumulated_incoming_damage": "Összes bejövő sebzés",
|
||||
"hud.settings.speech_bubble": "Szövegbuborék",
|
||||
"hud.settings.speech_bubble_dark_mode": "Szövegbuborék sötét mód",
|
||||
"hud.settings.speech_bubble_icon": "Szövegbuborék ikon",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Buff alla Minimappa",
|
||||
"hud.settings.toggle_bar_experience": "Attiva/Disattiva Barra dell'Esperienza",
|
||||
"hud.settings.scrolling_combat_text": "Testo del Combattimento a Scorrimento",
|
||||
"hud.settings.single_damage_number": "Numero Danni Singoli",
|
||||
"hud.settings.cumulated_damage": "Danno Accumulato",
|
||||
"hud.settings.incoming_damage": "Danno in Entrata",
|
||||
"hud.settings.cumulated_incoming_damage": "Danno in Entrata Accumulato",
|
||||
"hud.settings.speech_bubble": "Fumetto",
|
||||
"hud.settings.speech_bubble_self": "Mostra i Propri Fumetti",
|
||||
"hud.settings.speech_bubble_dark_mode": "Fumetto Modalità Scura",
|
||||
|
@ -22,10 +22,7 @@
|
||||
"hud.settings.buffs_mmap": "Buffs at Minimap",
|
||||
"hud.settings.toggle_bar_experience": "経験値バーの切り替え",
|
||||
"hud.settings.scrolling_combat_text": "戦闘メッセージのスクロール",
|
||||
"hud.settings.single_damage_number": "Single Damage Numbers",
|
||||
"hud.settings.cumulated_damage": "Cumulated Damage",
|
||||
"hud.settings.incoming_damage": "Incoming Damage",
|
||||
"hud.settings.cumulated_incoming_damage": "Cumulated Incoming Damage",
|
||||
"hud.settings.speech_bubble": "吹き出し",
|
||||
"hud.settings.speech_bubble_dark_mode": "ダークモード吹き出し",
|
||||
"hud.settings.speech_bubble_icon": "アイコン吹き出し",
|
||||
|
@ -20,10 +20,7 @@
|
||||
"hud.settings.toggle_shortcuts": "Toon Sneltoetsen",
|
||||
"hud.settings.toggle_bar_experience": "Toon Experience Balk",
|
||||
"hud.settings.scrolling_combat_text": "Pop-up Gevechtstext",
|
||||
"hud.settings.single_damage_number": "Aparte Schade Getallen",
|
||||
"hud.settings.cumulated_damage": "Cumulatieve Schade Getallen",
|
||||
"hud.settings.incoming_damage": "Inkomende Schade Getallen",
|
||||
"hud.settings.cumulated_incoming_damage": "Cumulatieve Inkomende Schade Getallen",
|
||||
"hud.settings.speech_bubble": "Spraakbubbel",
|
||||
"hud.settings.speech_bubble_dark_mode": "Donkere Modus",
|
||||
"hud.settings.speech_bubble_icon": "Spraakbubbel Icoon",
|
||||
|
@ -21,10 +21,7 @@
|
||||
"hud.settings.buffs_mmap": "Ikoner på Minimap",
|
||||
"hud.settings.toggle_bar_experience": "Veksle erfaringsbar",
|
||||
"hud.settings.scrolling_combat_text": "Rullende kamptekst",
|
||||
"hud.settings.single_damage_number": "Enkelt skadetall",
|
||||
"hud.settings.cumulated_damage": "Kumulert skade",
|
||||
"hud.settings.incoming_damage": "Innkommende skade",
|
||||
"hud.settings.cumulated_incoming_damage": "Kumulert innkommende skade",
|
||||
"hud.settings.speech_bubble": "Snakkeboble",
|
||||
"hud.settings.speech_bubble_dark_mode": "Mørk modus for snakkeboble",
|
||||
"hud.settings.speech_bubble_icon": "Snakkeboble ikon",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Wzmocnienia na minimapie",
|
||||
"hud.settings.toggle_bar_experience": "Przełącz pasek doświadczenia",
|
||||
"hud.settings.scrolling_combat_text": "Przewijanie tekstu podczas walki",
|
||||
"hud.settings.single_damage_number": "Ujednolicone numery obrażeń",
|
||||
"hud.settings.cumulated_damage": "Skumulowane obrażenia",
|
||||
"hud.settings.incoming_damage": "Otrzymywane obrażenia",
|
||||
"hud.settings.cumulated_incoming_damage": "Kalkulowane otrzymywane obrażenia",
|
||||
"hud.settings.speech_bubble": "Dymek rozmowy",
|
||||
"hud.settings.speech_bubble_self": "Pokazuj swój dymek rozmowy",
|
||||
"hud.settings.speech_bubble_dark_mode": "Dymek rozmowy w trybie ciemnym",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Buffs no Minimapa",
|
||||
"hud.settings.toggle_bar_experience": "Mostar/Ocultar Barra de Experiência",
|
||||
"hud.settings.scrolling_combat_text": "Texto de Combate Deslizante",
|
||||
"hud.settings.single_damage_number": "Números Únicos de Dano",
|
||||
"hud.settings.cumulated_damage": "Dano Acumulado",
|
||||
"hud.settings.incoming_damage": "Dano Recebido",
|
||||
"hud.settings.cumulated_incoming_damage": "Dano Recebido Acumulado",
|
||||
"hud.settings.speech_bubble": "Balão de Fala",
|
||||
"hud.settings.speech_bubble_dark_mode": "Balão de Fala Modo Escuro",
|
||||
"hud.settings.speech_bubble_icon": "Ícone do Balão de Fala",
|
||||
|
@ -19,10 +19,7 @@
|
||||
"hud.settings.toggle_shortcuts": "Mostar/Ocultar atalhos",
|
||||
"hud.settings.toggle_bar_experience": "Mostar/Ocultar barra de experiência",
|
||||
"hud.settings.scrolling_combat_text": "Texto de combate deslizante",
|
||||
"hud.settings.single_damage_number": "Números de dano únicos",
|
||||
"hud.settings.cumulated_damage": "Dano acumulado",
|
||||
"hud.settings.incoming_damage": "Dano recebido",
|
||||
"hud.settings.cumulated_incoming_damage": "Dano recebido acumulado",
|
||||
"hud.settings.energybar_numbers": "Números da barra de energia",
|
||||
"hud.settings.values": "Valores",
|
||||
"hud.settings.percentages": "Percentagens",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Баффы возле миникарте",
|
||||
"hud.settings.toggle_bar_experience": "Переключить панель опыта",
|
||||
"hud.settings.scrolling_combat_text": "Отображение урона/исцеления",
|
||||
"hud.settings.single_damage_number": "Отдельно нанесённый",
|
||||
"hud.settings.cumulated_damage": "Суммарно нанесённый",
|
||||
"hud.settings.incoming_damage": "Отдельно полученный",
|
||||
"hud.settings.cumulated_incoming_damage": "Суммарно полученный",
|
||||
"hud.settings.speech_bubble": "Диалоговое окно",
|
||||
"hud.settings.speech_bubble_self": "Показывать каждое отдельное окно",
|
||||
"hud.settings.speech_bubble_dark_mode": "Диалоговое окно (тёмная тема)",
|
||||
|
@ -24,10 +24,7 @@
|
||||
"hud.settings.buffs_mmap": "Бафови на Мапици",
|
||||
"hud.settings.toggle_bar_experience": "Ис/Укључи Траку са Искуством",
|
||||
"hud.settings.scrolling_combat_text": "Померајући Борбени Текст ",
|
||||
"hud.settings.single_damage_number": "Појединачне Ране",
|
||||
"hud.settings.cumulated_damage": "Акумулиране Ране",
|
||||
"hud.settings.incoming_damage": "Долазне Ране",
|
||||
"hud.settings.cumulated_incoming_damage": "Акумулирана Долазна Ране",
|
||||
"hud.settings.speech_bubble": "Говорни Облачић",
|
||||
"hud.settings.speech_bubble_dark_mode": "Тамни Говорни Облачић",
|
||||
"hud.settings.speech_bubble_icon": "Иконица Говорног Облачића",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "Effekter vid Minikartan",
|
||||
"hud.settings.toggle_bar_experience": "Visa/dölj erfarenhetsmätare",
|
||||
"hud.settings.scrolling_combat_text": "Rullande stridstext",
|
||||
"hud.settings.single_damage_number": "Ett enda skadenummer",
|
||||
"hud.settings.cumulated_damage": "Sammanlagd skada",
|
||||
"hud.settings.incoming_damage": "Inkommande skada",
|
||||
"hud.settings.cumulated_incoming_damage": "Sammanlagd inkommande skada",
|
||||
"hud.settings.speech_bubble": "Pratbubbla",
|
||||
"hud.settings.speech_bubble_self": "Visa egna pratbubblor",
|
||||
"hud.settings.speech_bubble_dark_mode": "Pratbubbla mörkt läge",
|
||||
|
@ -25,10 +25,7 @@
|
||||
"hud.settings.buffs_mmap": "แสดงสถานะที่แผนที่",
|
||||
"hud.settings.toggle_bar_experience": "เปิด/ปิดแถบค่าประสบการณ์",
|
||||
"hud.settings.scrolling_combat_text": "ความเสียหายที่ทำได้",
|
||||
"hud.settings.single_damage_number": "แสดงแต่ละเลขแยกกัน",
|
||||
"hud.settings.cumulated_damage": "แสดงเลขรวมกันเป็นเลขเดียว",
|
||||
"hud.settings.incoming_damage": "ความเสียหายที่ได้รับ",
|
||||
"hud.settings.cumulated_incoming_damage": "ความเสียหายที่ได้รับแบบรวม",
|
||||
"hud.settings.speech_bubble": "ลูกโป่งคำพูด",
|
||||
"hud.settings.speech_bubble_self": "แสดงลูกโป่งคำพูด",
|
||||
"hud.settings.speech_bubble_dark_mode": "แสดงลูกดป่งคำพูดแบบมืด",
|
||||
|
@ -22,10 +22,7 @@
|
||||
"hud.settings.buffs_mmap": "Etkiler haritanın yanında",
|
||||
"hud.settings.toggle_bar_experience": "Tecrübe çubuğunu aç/kapa",
|
||||
"hud.settings.scrolling_combat_text": "Verilen/Alınan Hasar Yazısı",
|
||||
"hud.settings.single_damage_number": "Verilen Hasarı Tek Tek Göster",
|
||||
"hud.settings.cumulated_damage": "Toplam Verilen Hasarı Göster",
|
||||
"hud.settings.incoming_damage": "Alınan Hasarı Tek Tek Göster",
|
||||
"hud.settings.cumulated_incoming_damage": "Toplam Alınan Hasarı Göster",
|
||||
"hud.settings.speech_bubble": "Konuşma balonu",
|
||||
"hud.settings.speech_bubble_dark_mode": "Konuşma balonunda karanlık tema kullan",
|
||||
"hud.settings.speech_bubble_icon": "Konuşma balonunda ikon göster",
|
||||
|
@ -24,10 +24,7 @@
|
||||
"hud.settings.buffs_mmap": "Бафи біля Мінімапи",
|
||||
"hud.settings.toggle_bar_experience": "Панель досвіду",
|
||||
"hud.settings.scrolling_combat_text": "Відображення Пошкоджень/Зцілень",
|
||||
"hud.settings.single_damage_number": "Роздільно нанесені Гравцем",
|
||||
"hud.settings.cumulated_damage": "Сумарно нанесені Гравцем",
|
||||
"hud.settings.incoming_damage": "Роздільно отримані Гравцем",
|
||||
"hud.settings.cumulated_incoming_damage": "Сумарно отримані Гравцем",
|
||||
"hud.settings.speech_bubble": "Діалоги",
|
||||
"hud.settings.speech_bubble_dark_mode": "Темний режим",
|
||||
"hud.settings.speech_bubble_icon": "Піктограма",
|
||||
|
@ -24,10 +24,7 @@
|
||||
"hud.settings.buffs_mmap": "Buffs tại Minimap",
|
||||
"hud.settings.toggle_bar_experience": "Bật tắt thanh kinh nghiệm",
|
||||
"hud.settings.scrolling_combat_text": "Thông Tin Chiến Đấu",
|
||||
"hud.settings.single_damage_number": "Sát thương từng đòn đánh",
|
||||
"hud.settings.cumulated_damage": "Sát thương tích lũy",
|
||||
"hud.settings.incoming_damage": "Sát thương nhận phải",
|
||||
"hud.settings.cumulated_incoming_damage": "Sát thương tích lũy nhận phải",
|
||||
"hud.settings.speech_bubble": "Bong Bóng Thoại",
|
||||
"hud.settings.speech_bubble_dark_mode": "Chế độ tối màu",
|
||||
"hud.settings.speech_bubble_icon": "Biểu tượng bong bóng thoại",
|
||||
|
@ -22,10 +22,7 @@
|
||||
"hud.settings.buffs_mmap": "增益效果显示在小地图旁",
|
||||
"hud.settings.toggle_bar_experience": "显示经验条",
|
||||
"hud.settings.scrolling_combat_text": "战斗信息",
|
||||
"hud.settings.single_damage_number": "单次伤害",
|
||||
"hud.settings.cumulated_damage": "累计伤害",
|
||||
"hud.settings.incoming_damage": "所受伤害",
|
||||
"hud.settings.cumulated_incoming_damage": "累计所受伤害",
|
||||
"hud.settings.speech_bubble": "对话框",
|
||||
"hud.settings.speech_bubble_dark_mode": "对话框启用暗色模式",
|
||||
"hud.settings.speech_bubble_icon": "对话框显示图标",
|
||||
|
@ -20,10 +20,7 @@
|
||||
"hud.settings.toggle_shortcuts": "顯示快捷鍵",
|
||||
"hud.settings.toggle_bar_experience": "顯示經驗條",
|
||||
"hud.settings.scrolling_combat_text": "戰鬥訊息",
|
||||
"hud.settings.single_damage_number": "單一傷害",
|
||||
"hud.settings.cumulated_damage": "累積傷害",
|
||||
"hud.settings.incoming_damage": "所受傷害",
|
||||
"hud.settings.cumulated_incoming_damage": "累積所受傷害",
|
||||
"hud.settings.energybar_numbers": "能量條",
|
||||
"hud.settings.values": "數字",
|
||||
"hud.settings.percentages": "百分比",
|
||||
|
@ -235,10 +235,11 @@ impl Attack {
|
||||
self.crit_multiplier,
|
||||
strength_modifier,
|
||||
time,
|
||||
damage.instance,
|
||||
);
|
||||
let applied_damage = -change.amount;
|
||||
accumulated_damage += applied_damage;
|
||||
emit_outcome(Outcome::Damage { pos: target.pos });
|
||||
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
entity: target.entity,
|
||||
@ -257,6 +258,8 @@ impl Attack {
|
||||
by: attacker.map(|x| x.into()),
|
||||
cause: Some(damage.damage.source),
|
||||
time,
|
||||
crit: is_crit,
|
||||
instance: damage.instance,
|
||||
};
|
||||
emit(ServerEvent::HealthChange {
|
||||
entity: target.entity,
|
||||
@ -295,6 +298,8 @@ impl Attack {
|
||||
amount: health_change,
|
||||
by: attacker.map(|x| x.into()),
|
||||
cause: Some(damage.damage.source),
|
||||
instance: damage.instance,
|
||||
crit: false,
|
||||
time,
|
||||
};
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -354,6 +359,8 @@ impl Attack {
|
||||
by: attacker.map(|a| a.into()),
|
||||
cause: None,
|
||||
time,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -386,6 +393,8 @@ impl Attack {
|
||||
by: attacker.map(|a| a.into()),
|
||||
cause: None,
|
||||
time,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -497,6 +506,8 @@ impl Attack {
|
||||
by: attacker.map(|a| a.into()),
|
||||
cause: None,
|
||||
time,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -529,6 +540,8 @@ impl Attack {
|
||||
by: attacker.map(|a| a.into()),
|
||||
cause: None,
|
||||
time,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
if change.amount.abs() > Health::HEALTH_EPSILON {
|
||||
emit(ServerEvent::HealthChange {
|
||||
@ -618,15 +631,18 @@ pub struct AttackDamage {
|
||||
damage: Damage,
|
||||
target: Option<GroupTarget>,
|
||||
effects: Vec<CombatEffect>,
|
||||
/// A random ID, used to group up attacks
|
||||
instance: u64,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
impl AttackDamage {
|
||||
pub fn new(damage: Damage, target: Option<GroupTarget>) -> Self {
|
||||
pub fn new(damage: Damage, target: Option<GroupTarget>, instance: u64) -> Self {
|
||||
Self {
|
||||
damage,
|
||||
target,
|
||||
effects: Vec::new(),
|
||||
instance,
|
||||
}
|
||||
}
|
||||
|
||||
@ -818,6 +834,7 @@ impl Damage {
|
||||
crit_mult: f32,
|
||||
damage_modifier: f32,
|
||||
time: Time,
|
||||
instance: u64,
|
||||
) -> HealthChange {
|
||||
let mut damage = self.value * damage_modifier;
|
||||
let critdamage = if is_crit {
|
||||
@ -841,6 +858,8 @@ impl Damage {
|
||||
by: damage_contributor,
|
||||
cause: Some(self.source),
|
||||
time,
|
||||
crit: is_crit,
|
||||
instance,
|
||||
}
|
||||
},
|
||||
DamageSource::Falling => {
|
||||
@ -853,6 +872,8 @@ impl Damage {
|
||||
by: None,
|
||||
cause: Some(self.source),
|
||||
time,
|
||||
crit: false,
|
||||
instance,
|
||||
}
|
||||
},
|
||||
DamageSource::Buff(_) | DamageSource::Other => HealthChange {
|
||||
@ -860,6 +881,8 @@ impl Damage {
|
||||
by: None,
|
||||
cause: Some(self.source),
|
||||
time,
|
||||
crit: false,
|
||||
instance,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ pub enum BuffEffect {
|
||||
rate: f32,
|
||||
accumulated: f32,
|
||||
kind: ModifierKind,
|
||||
instance: u64,
|
||||
},
|
||||
/// Periodically consume entity energy
|
||||
EnergyChangeOverTime {
|
||||
@ -234,12 +235,14 @@ impl Buff {
|
||||
) -> Self {
|
||||
// Normalized nonlinear scaling
|
||||
let nn_scaling = |a| a / (a + 0.5);
|
||||
let instance = rand::random();
|
||||
let (effects, time) = match kind {
|
||||
BuffKind::Bleeding => (
|
||||
vec![BuffEffect::HealthChangeOverTime {
|
||||
rate: -data.strength,
|
||||
accumulated: 0.0,
|
||||
kind: ModifierKind::Additive,
|
||||
instance,
|
||||
}],
|
||||
data.duration,
|
||||
),
|
||||
@ -248,6 +251,7 @@ impl Buff {
|
||||
rate: data.strength,
|
||||
accumulated: 0.0,
|
||||
kind: ModifierKind::Additive,
|
||||
instance,
|
||||
}],
|
||||
data.duration,
|
||||
),
|
||||
@ -256,6 +260,7 @@ impl Buff {
|
||||
rate: data.strength,
|
||||
accumulated: 0.0,
|
||||
kind: ModifierKind::Fractional,
|
||||
instance,
|
||||
}],
|
||||
data.duration,
|
||||
),
|
||||
@ -271,6 +276,7 @@ impl Buff {
|
||||
rate: -1.0,
|
||||
accumulated: 0.0,
|
||||
kind: ModifierKind::Additive,
|
||||
instance,
|
||||
},
|
||||
],
|
||||
data.duration,
|
||||
@ -304,6 +310,7 @@ impl Buff {
|
||||
rate: -data.strength,
|
||||
accumulated: 0.0,
|
||||
kind: ModifierKind::Additive,
|
||||
instance,
|
||||
}],
|
||||
data.duration,
|
||||
),
|
||||
@ -322,6 +329,7 @@ impl Buff {
|
||||
rate: -data.strength * 4.0,
|
||||
accumulated: 0.0,
|
||||
kind: ModifierKind::Additive,
|
||||
instance,
|
||||
},
|
||||
],
|
||||
data.duration,
|
||||
@ -333,6 +341,7 @@ impl Buff {
|
||||
rate: data.strength * 10.0,
|
||||
accumulated: 0.0,
|
||||
kind: ModifierKind::Additive,
|
||||
instance,
|
||||
},
|
||||
],
|
||||
data.duration,
|
||||
|
@ -24,6 +24,10 @@ pub struct HealthChange {
|
||||
pub cause: Option<DamageSource>,
|
||||
/// The time that the health change occurred at
|
||||
pub time: Time,
|
||||
/// A boolean that tells you if the change was a crit
|
||||
pub crit: bool,
|
||||
/// A random ID, used to group up health changes from the same attack
|
||||
pub instance: u64,
|
||||
}
|
||||
|
||||
impl HealthChange {
|
||||
@ -132,7 +136,9 @@ impl Health {
|
||||
amount: 0.0,
|
||||
by: None,
|
||||
cause: None,
|
||||
crit: false,
|
||||
time: Time(0.0),
|
||||
instance: rand::random(),
|
||||
},
|
||||
is_dead: false,
|
||||
damage_contributors: HashMap::new(),
|
||||
@ -151,7 +157,8 @@ impl Health {
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn change_by(&mut self, change: HealthChange) {
|
||||
/// Returns a boolean if the delta was not zero.
|
||||
pub fn change_by(&mut self, change: HealthChange) -> bool {
|
||||
let prev_health = i64::from(self.current);
|
||||
self.current = (((self.current() + change.amount).clamp(0.0, f32::from(Self::MAX_HEALTH))
|
||||
* Self::SCALING_FACTOR_FLOAT) as u32)
|
||||
@ -179,6 +186,7 @@ impl Health {
|
||||
(change.time.0 - last_damage_time.0) < DAMAGE_CONTRIB_PRUNE_SECS
|
||||
});
|
||||
}
|
||||
delta != 0
|
||||
}
|
||||
|
||||
pub fn damage_contributions(&self) -> impl Iterator<Item = (&DamageContributor, &u64)> {
|
||||
@ -210,7 +218,9 @@ impl Health {
|
||||
amount: 0.0,
|
||||
by: None,
|
||||
cause: None,
|
||||
crit: false,
|
||||
time: Time(0.0),
|
||||
instance: rand::random(),
|
||||
},
|
||||
is_dead: false,
|
||||
damage_contributors: HashMap::new(),
|
||||
@ -244,6 +254,8 @@ mod tests {
|
||||
time: Time(123.0),
|
||||
by: Some(damage_contrib),
|
||||
cause: None,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
|
||||
health.change_by(health_change);
|
||||
@ -269,6 +281,8 @@ mod tests {
|
||||
time: Time(123.0),
|
||||
by: Some(damage_contrib),
|
||||
cause: None,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
|
||||
health.change_by(health_change);
|
||||
@ -288,6 +302,8 @@ mod tests {
|
||||
time: Time(123.0),
|
||||
by: Some(damage_contrib),
|
||||
cause: None,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
health.change_by(health_change);
|
||||
health.change_by(health_change);
|
||||
@ -313,6 +329,8 @@ mod tests {
|
||||
time: Time(10.0),
|
||||
by: Some(damage_contrib1),
|
||||
cause: None,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
health.change_by(health_change);
|
||||
|
||||
@ -322,6 +340,8 @@ mod tests {
|
||||
time: Time(100.0),
|
||||
by: Some(damage_contrib2),
|
||||
cause: None,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
health.change_by(health_change);
|
||||
|
||||
@ -335,6 +355,8 @@ mod tests {
|
||||
time: Time(620.0),
|
||||
by: Some(damage_contrib2),
|
||||
cause: None,
|
||||
crit: false,
|
||||
instance: rand::random(),
|
||||
};
|
||||
health.change_by(health_change);
|
||||
|
||||
|
@ -57,7 +57,7 @@ impl MeleeConstructor {
|
||||
scaling the melee attack."
|
||||
)
|
||||
}
|
||||
|
||||
let instance = rand::random();
|
||||
let attack = match self.kind {
|
||||
Slash {
|
||||
damage,
|
||||
@ -80,6 +80,7 @@ impl MeleeConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
)
|
||||
.with_effect(buff);
|
||||
|
||||
@ -128,6 +129,7 @@ impl MeleeConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
)
|
||||
.with_effect(buff);
|
||||
|
||||
@ -170,6 +172,7 @@ impl MeleeConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
|
||||
if let Some(damage_effect) = self.damage_effect {
|
||||
@ -210,6 +213,7 @@ impl MeleeConstructor {
|
||||
value: damage,
|
||||
},
|
||||
None,
|
||||
instance,
|
||||
)
|
||||
.with_effect(lifesteal);
|
||||
|
||||
@ -244,6 +248,7 @@ impl MeleeConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
|
||||
if let Some(damage_effect) = self.damage_effect {
|
||||
|
@ -99,6 +99,7 @@ impl ProjectileConstructor {
|
||||
crit_mult: f32,
|
||||
buff_strength: f32,
|
||||
) -> Projectile {
|
||||
let instance = rand::random();
|
||||
use ProjectileConstructor::*;
|
||||
match self {
|
||||
Arrow {
|
||||
@ -129,6 +130,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
)
|
||||
.with_effect(buff);
|
||||
let attack = Attack::default()
|
||||
@ -169,6 +171,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
)
|
||||
.with_effect(buff);
|
||||
let attack = Attack::default()
|
||||
@ -207,6 +210,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
@ -250,6 +254,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
@ -286,6 +291,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
@ -337,6 +343,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
@ -373,6 +380,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
@ -424,6 +432,7 @@ impl ProjectileConstructor {
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
|
@ -1,9 +1,18 @@
|
||||
use crate::{comp, uid::Uid};
|
||||
use crate::{combat::DamageContributor, comp, uid::Uid};
|
||||
use comp::{beam, item::Reagent, poise::PoiseState, skillset::SkillGroupKind, UtteranceKind};
|
||||
use hashbrown::HashSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct HealthChangeInfo {
|
||||
pub amount: f32,
|
||||
pub crit: bool,
|
||||
pub target: Uid,
|
||||
pub by: Option<DamageContributor>,
|
||||
pub instance: u64,
|
||||
}
|
||||
|
||||
/// An outcome represents the final result of an instantaneous event. It implies
|
||||
/// that said event has already occurred. It is not a request for that event to
|
||||
/// occur, nor is it something that may be cancelled or otherwise altered. Its
|
||||
@ -58,8 +67,9 @@ pub enum Outcome {
|
||||
pos: Vec3<f32>,
|
||||
body: comp::Body,
|
||||
},
|
||||
Damage {
|
||||
HealthChange {
|
||||
pos: Vec3<f32>,
|
||||
info: HealthChangeInfo,
|
||||
},
|
||||
Death {
|
||||
pos: Vec3<f32>,
|
||||
@ -96,7 +106,7 @@ impl Outcome {
|
||||
| Outcome::Beam { pos, .. }
|
||||
| Outcome::SkillPointGain { pos, .. }
|
||||
| Outcome::SummonedCreature { pos, .. }
|
||||
| Outcome::Damage { pos, .. }
|
||||
| Outcome::HealthChange { pos, .. }
|
||||
| Outcome::Death { pos, .. }
|
||||
| Outcome::Block { pos, .. }
|
||||
| Outcome::PoiseChange { pos, .. }
|
||||
|
@ -116,6 +116,7 @@ impl CharacterBehavior for Data {
|
||||
value: self.static_data.damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
rand::random(),
|
||||
);
|
||||
if let Some(effect) = self.static_data.damage_effect {
|
||||
damage = damage.with_effect(effect);
|
||||
|
@ -264,6 +264,7 @@ impl CharacterBehavior for Data {
|
||||
value: damage as f32,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
rand::random(),
|
||||
);
|
||||
if let Some(effect) = self.static_data.stage_data[stage_index].damage_effect {
|
||||
damage = damage.with_effect(effect);
|
||||
|
@ -96,6 +96,7 @@ impl CharacterBehavior for Data {
|
||||
value: self.static_data.damage as f32,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
rand::random(),
|
||||
);
|
||||
if let Some(effect) = self.static_data.damage_effect {
|
||||
damage = damage.with_effect(effect);
|
||||
|
@ -241,6 +241,7 @@ impl<'a> System<'a> for Sys {
|
||||
rate,
|
||||
accumulated,
|
||||
kind,
|
||||
instance,
|
||||
} => {
|
||||
*accumulated += *rate * dt;
|
||||
// Apply health change only once per second, per health, or
|
||||
@ -248,7 +249,7 @@ impl<'a> System<'a> for Sys {
|
||||
if accumulated.abs() > rate.abs().min(1.0)
|
||||
|| buff.time.map_or(false, |dur| dur == Duration::default())
|
||||
{
|
||||
let (cause, by) = if *accumulated < 0.0 {
|
||||
let (cause, by) = if *accumulated != 0.0 {
|
||||
(Some(DamageSource::Buff(buff.kind)), buff_owner)
|
||||
} else {
|
||||
(None, None)
|
||||
@ -274,6 +275,8 @@ impl<'a> System<'a> for Sys {
|
||||
by: damage_contributor,
|
||||
cause,
|
||||
time: *read_data.time,
|
||||
crit: false,
|
||||
instance: *instance,
|
||||
},
|
||||
});
|
||||
*accumulated = 0.0;
|
||||
|
@ -1056,7 +1056,9 @@ fn handle_health(
|
||||
amount: hp - health.current(),
|
||||
by: None,
|
||||
cause: None,
|
||||
crit: false,
|
||||
time: *time,
|
||||
instance: rand::random(),
|
||||
};
|
||||
health.change_by(change);
|
||||
Ok(())
|
||||
|
@ -23,7 +23,7 @@ use common::{
|
||||
Player, Poise, Pos, SkillSet, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
outcome::Outcome,
|
||||
outcome::{HealthChangeInfo, Outcome},
|
||||
resources::Time,
|
||||
rtsim::RtSimEntity,
|
||||
terrain::{Block, BlockKind, TerrainGrid},
|
||||
@ -67,7 +67,26 @@ pub fn handle_poise(server: &Server, entity: EcsEntity, change: comp::PoiseChang
|
||||
pub fn handle_health_change(server: &Server, entity: EcsEntity, change: HealthChange) {
|
||||
let ecs = &server.state.ecs();
|
||||
if let Some(mut health) = ecs.write_storage::<Health>().get_mut(entity) {
|
||||
health.change_by(change);
|
||||
// If the change amount was not zero
|
||||
let changed = health.change_by(change);
|
||||
if let (Some(pos), Some(uid)) = (
|
||||
ecs.read_storage::<Pos>().get(entity),
|
||||
ecs.read_storage::<Uid>().get(entity),
|
||||
) {
|
||||
if changed {
|
||||
let outcomes = ecs.write_resource::<EventBus<Outcome>>();
|
||||
outcomes.emit_now(Outcome::HealthChange {
|
||||
pos: pos.0,
|
||||
info: HealthChangeInfo {
|
||||
amount: change.amount,
|
||||
by: change.by,
|
||||
target: *uid,
|
||||
crit: change.crit,
|
||||
instance: change.instance,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// This if statement filters out anything under 5 damage, for DOT ticks
|
||||
// TODO: Find a better way to separate direct damage from DOT here
|
||||
@ -573,10 +592,20 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
|
||||
stats.get(entity),
|
||||
&msm,
|
||||
);
|
||||
let change =
|
||||
damage.calculate_health_change(damage_reduction, None, false, 0.0, 1.0, *time);
|
||||
let change = damage.calculate_health_change(
|
||||
damage_reduction,
|
||||
None,
|
||||
false,
|
||||
0.0,
|
||||
1.0,
|
||||
*time,
|
||||
rand::random(),
|
||||
);
|
||||
health.change_by(change);
|
||||
let server_eventbus = ecs.read_resource::<EventBus<ServerEvent>>();
|
||||
server_eventbus.emit_now(ServerEvent::HealthChange { entity, change });
|
||||
}
|
||||
|
||||
// Handle poise change
|
||||
if let Some(mut poise) = ecs.write_storage::<comp::Poise>().get_mut(entity) {
|
||||
let poise_damage = -(mass.0 * vel.magnitude_squared() / 1500.0);
|
||||
|
@ -159,6 +159,7 @@ impl StateExt for State {
|
||||
0.0,
|
||||
1.0,
|
||||
*time,
|
||||
rand::random(),
|
||||
);
|
||||
self.ecs()
|
||||
.write_storage::<comp::Health>()
|
||||
|
@ -95,7 +95,7 @@ use common::{
|
||||
item::{ItemDefinitionId, ItemKind, ToolKind},
|
||||
object,
|
||||
poise::PoiseState,
|
||||
quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType,
|
||||
quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType, Health,
|
||||
InventoryUpdateEvent, UtteranceKind,
|
||||
},
|
||||
outcome::Outcome,
|
||||
@ -514,9 +514,12 @@ impl SfxMgr {
|
||||
false,
|
||||
);
|
||||
},
|
||||
Outcome::Damage { pos, .. } => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Damage);
|
||||
audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false);
|
||||
Outcome::HealthChange { pos, info, .. } => {
|
||||
// Don't emit sound effects from positive damage (healing)
|
||||
if info.amount < Health::HEALTH_EPSILON {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Damage);
|
||||
audio.emit_sfx(sfx_trigger_item, *pos, Some(1.5), false);
|
||||
}
|
||||
},
|
||||
Outcome::Death { pos, .. } => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Death);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use common::comp::Ori;
|
||||
use common::{comp::Ori, outcome::HealthChangeInfo};
|
||||
use specs::Component;
|
||||
use specs_idvs::IdvStorage;
|
||||
use vek::*;
|
||||
@ -8,8 +8,9 @@ use vek::*;
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct HpFloater {
|
||||
pub timer: f32,
|
||||
// Numbers of times significant damage has been dealt
|
||||
pub hp_change: f32,
|
||||
// Used for the "jumping" animation of the HpFloater whenever it changes it's value
|
||||
pub jump_timer: f32,
|
||||
pub info: HealthChangeInfo,
|
||||
// Used for randomly offsetting
|
||||
pub rand: f32,
|
||||
}
|
||||
@ -17,9 +18,7 @@ pub struct HpFloater {
|
||||
pub struct HpFloaterList {
|
||||
// Order oldest to newest
|
||||
pub floaters: Vec<HpFloater>,
|
||||
// Keep from spawning more floaters from same hp change
|
||||
// Note: this can't detect a change if equivalent healing and damage take place simultaneously
|
||||
pub last_hp: f32,
|
||||
|
||||
// The time since you last damaged this entity
|
||||
// Used to display nametags outside normal range if this time is below a certain value
|
||||
pub time_since_last_dmg_by_me: Option<f32>,
|
||||
|
@ -1,16 +1,15 @@
|
||||
use crate::ecs::comp::{HpFloater, HpFloaterList};
|
||||
use crate::ecs::comp::HpFloaterList;
|
||||
use common::{
|
||||
comp::{Health, Pos},
|
||||
resources::{DeltaTime, PlayerEntity},
|
||||
uid::Uid,
|
||||
};
|
||||
use common_ecs::{Job, Origin, Phase, System};
|
||||
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
|
||||
|
||||
// How long floaters last (in seconds)
|
||||
pub const HP_SHOWTIME: f32 = 3.0;
|
||||
pub const CRIT_SHOWTIME: f32 = 0.7;
|
||||
pub const MY_HP_SHOWTIME: f32 = 2.5;
|
||||
pub const HP_ACCUMULATETIME: f32 = 1.0;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Sys;
|
||||
@ -19,7 +18,6 @@ impl<'a> System<'a> for Sys {
|
||||
Entities<'a>,
|
||||
Read<'a, PlayerEntity>,
|
||||
Read<'a, DeltaTime>,
|
||||
ReadStorage<'a, Uid>,
|
||||
ReadStorage<'a, Pos>,
|
||||
ReadStorage<'a, Health>,
|
||||
WriteStorage<'a, HpFloaterList>,
|
||||
@ -32,88 +30,20 @@ impl<'a> System<'a> for Sys {
|
||||
#[allow(clippy::blocks_in_if_conditions)] // TODO: Pending review in #587
|
||||
fn run(
|
||||
_job: &mut Job<Self>,
|
||||
(entities, my_entity, dt, uids, pos, healths, mut hp_floater_lists): Self::SystemData,
|
||||
(entities, my_entity, dt, pos, healths, mut hp_floater_lists): Self::SystemData,
|
||||
) {
|
||||
// Add hp floater lists to all entities with health and a position
|
||||
// Note: necessary in order to know last_hp
|
||||
for (entity, last_hp) in (&entities, &healths, &pos, !&hp_floater_lists)
|
||||
for entity in (&entities, &healths, &pos, !&hp_floater_lists)
|
||||
.join()
|
||||
.map(|(e, h, _, _)| (e, h.current()))
|
||||
.map(|(e, _, _, _)| e)
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
let _ = hp_floater_lists.insert(entity, HpFloaterList {
|
||||
floaters: Vec::new(),
|
||||
last_hp,
|
||||
time_since_last_dmg_by_me: None,
|
||||
});
|
||||
}
|
||||
|
||||
// Add hp floaters to all entities that have been damaged
|
||||
let my_uid = my_entity.0.and_then(|entity| uids.get(entity));
|
||||
for (entity, health, hp_floater_list) in (&entities, &healths, &mut hp_floater_lists).join()
|
||||
{
|
||||
// Increment timer for time since last damaged by me
|
||||
hp_floater_list
|
||||
.time_since_last_dmg_by_me
|
||||
.as_mut()
|
||||
.map(|t| *t += dt.0);
|
||||
|
||||
// Check if health has changed (won't work if damaged and then healed with
|
||||
// equivalently in the same frame)
|
||||
if (hp_floater_list.last_hp - health.current()).abs() > Health::HEALTH_EPSILON {
|
||||
hp_floater_list.last_hp = health.current();
|
||||
// TODO: What if multiple health changes occurred since last check here
|
||||
// Also, If we make health store a vec of the last_changes (from say the last
|
||||
// frame), what if the client receives the health component from
|
||||
// two different server ticks at once, then one will be lost
|
||||
// (tbf this is probably a rare occurance and the results
|
||||
// would just be a transient glitch in the display of these damage numbers)
|
||||
// (maybe health changes could be sent to the client as a list
|
||||
// of events)
|
||||
if match health.last_change.by.map(|x| x.uid()) {
|
||||
// HealthSource::Damage { by: Some(by), .. }
|
||||
// | HealthSource::Heal { by: Some(by) } => {
|
||||
// let by_me = my_uid.map_or(false, |&uid| by == uid);
|
||||
// // If the attack was by me also reset this timer
|
||||
// if by_me {
|
||||
// hp_floater_list.time_since_last_dmg_by_me = Some(0.0);
|
||||
// }
|
||||
// my_entity.0 == Some(entity) || by_me
|
||||
// },
|
||||
// HealthSource::Suicide => my_entity.0 == Some(entity),
|
||||
// HealthSource::World => my_entity.0 == Some(entity),
|
||||
// HealthSource::LevelUp => my_entity.0 == Some(entity),
|
||||
// HealthSource::Command => true,
|
||||
// HealthSource::Item => true,
|
||||
// _ => false,
|
||||
Some(by) => {
|
||||
let by_me = my_uid.map_or(false, |&uid| by == uid);
|
||||
// If the attack was by me also reset this timer
|
||||
if by_me {
|
||||
hp_floater_list.time_since_last_dmg_by_me = Some(0.0);
|
||||
}
|
||||
my_entity.0 == Some(entity) || by_me
|
||||
},
|
||||
None => false,
|
||||
} {
|
||||
let last_floater = hp_floater_list.floaters.last_mut();
|
||||
match last_floater {
|
||||
Some(f) if f.timer < HP_ACCUMULATETIME => {
|
||||
//TODO: Add "jumping" animation on floater when it changes its value
|
||||
f.hp_change += health.last_change.amount;
|
||||
},
|
||||
_ => {
|
||||
hp_floater_list.floaters.push(HpFloater {
|
||||
timer: 0.0,
|
||||
hp_change: health.last_change.amount,
|
||||
rand: rand::random(),
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove floater lists on entities without health or without position
|
||||
for entity in (&entities, !&healths, &hp_floater_lists)
|
||||
.join()
|
||||
@ -131,30 +61,29 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
|
||||
// Maintain existing floaters
|
||||
for (
|
||||
entity,
|
||||
HpFloaterList {
|
||||
ref mut floaters,
|
||||
ref last_hp,
|
||||
..
|
||||
},
|
||||
) in (&entities, &mut hp_floater_lists).join()
|
||||
{
|
||||
for mut floater in floaters.iter_mut() {
|
||||
for (entity, hp_floater_list) in (&entities, &mut hp_floater_lists).join() {
|
||||
// Increment timer for time since last damaged by me
|
||||
hp_floater_list
|
||||
.time_since_last_dmg_by_me
|
||||
.as_mut()
|
||||
.map(|t| *t += dt.0);
|
||||
|
||||
for mut floater in hp_floater_list.floaters.iter_mut() {
|
||||
// Increment timer
|
||||
floater.timer += dt.0;
|
||||
floater.jump_timer += dt.0;
|
||||
}
|
||||
// Clear floaters if newest floater is past show time or health runs out
|
||||
if floaters.last().map_or(false, |f| {
|
||||
|
||||
// Clear floaters if newest floater is past show time
|
||||
if hp_floater_list.floaters.last().map_or(false, |f| {
|
||||
f.timer
|
||||
> if Some(entity) != my_entity.0 {
|
||||
HP_SHOWTIME
|
||||
} else {
|
||||
MY_HP_SHOWTIME
|
||||
}
|
||||
|| last_hp.abs() < Health::HEALTH_EPSILON
|
||||
}) {
|
||||
floaters.clear();
|
||||
hp_floater_list.floaters.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -77,15 +77,16 @@ widget_ids! {
|
||||
sct_title,
|
||||
sct_show_text,
|
||||
sct_show_radio,
|
||||
sct_single_dmg_text,
|
||||
sct_single_dmg_radio,
|
||||
sct_show_batch_text,
|
||||
sct_show_batch_radio,
|
||||
sct_batched_dmg_radio,
|
||||
sct_inc_dmg_text,
|
||||
sct_inc_dmg_radio,
|
||||
sct_batch_inc_text,
|
||||
sct_batch_inc_radio,
|
||||
sct_round_dmg_text,
|
||||
sct_round_dmg_radio,
|
||||
sct_dmg_accum_duration_slider,
|
||||
sct_dmg_accum_duration_text,
|
||||
sct_dmg_accum_duration_value,
|
||||
sct_show_inc_dmg_text,
|
||||
sct_show_inc_dmg_radio,
|
||||
sct_inc_dmg_accum_duration_slider,
|
||||
sct_inc_dmg_accum_duration_text,
|
||||
sct_inc_dmg_accum_duration_value,
|
||||
//
|
||||
speech_bubble_text,
|
||||
speech_bubble_self_text,
|
||||
@ -94,6 +95,10 @@ widget_ids! {
|
||||
speech_bubble_dark_mode_button,
|
||||
speech_bubble_icon_text,
|
||||
speech_bubble_icon_button,
|
||||
//
|
||||
experience_numbers_title,
|
||||
accum_experience_text,
|
||||
accum_experience_button,
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,12 +716,12 @@ impl<'a> Widget for Interface<'a> {
|
||||
/*Scrolling Combat text
|
||||
|
||||
O Show Damage Numbers
|
||||
O Show single Damage Numbers
|
||||
O Show batched dealt Damage
|
||||
Damage Accumulation Duration:
|
||||
[0s ----I----2s]
|
||||
O Show incoming Damage
|
||||
O Batch incoming Numbers
|
||||
|
||||
Number Display Duration: 1s ----I----5s
|
||||
Incoming Damage Accumulation Duration:
|
||||
[0s ----I----2s]
|
||||
O Round Damage Numbers
|
||||
*/
|
||||
// SCT/ Scrolling Combat Text
|
||||
Text::new(
|
||||
@ -754,105 +759,152 @@ impl<'a> Widget for Interface<'a> {
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_show_text, ui);
|
||||
if self.global_state.settings.interface.sct {
|
||||
// Toggle single damage numbers
|
||||
let show_sct_damage_batch = !ToggleButton::new(
|
||||
!self.global_state.settings.interface.sct_damage_batch,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.sct_show_text, 8.0)
|
||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||
.set(state.ids.sct_single_dmg_radio, ui);
|
||||
let sct_dmg_accum_duration =
|
||||
self.global_state.settings.interface.sct_dmg_accum_duration;
|
||||
let sct_inc_dmg_accum_duration = self
|
||||
.global_state
|
||||
.settings
|
||||
.interface
|
||||
.sct_inc_dmg_accum_duration;
|
||||
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.single_damage_number"),
|
||||
.get("hud.settings.damage_accumulation_duration"),
|
||||
)
|
||||
.right_from(state.ids.sct_single_dmg_radio, 10.0)
|
||||
.down_from(state.ids.sct_show_radio, 8.0)
|
||||
.right_from(state.ids.sct_show_radio, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.sct_single_dmg_radio)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_single_dmg_text, ui);
|
||||
// Toggle Batched Damage
|
||||
let show_sct_damage_batch = ToggleButton::new(
|
||||
show_sct_damage_batch,
|
||||
.set(state.ids.sct_dmg_accum_duration_text, ui);
|
||||
|
||||
if let Some(new_val) = ImageSlider::continuous(
|
||||
sct_dmg_accum_duration,
|
||||
0.0,
|
||||
2.0,
|
||||
self.imgs.slider_indicator,
|
||||
self.imgs.slider,
|
||||
)
|
||||
.w_h(104.0, 22.0)
|
||||
.down_from(state.ids.sct_dmg_accum_duration_text, 8.0)
|
||||
.track_breadth(12.0)
|
||||
.slider_length(10.0)
|
||||
.pad_track((5.0, 5.0))
|
||||
.set(state.ids.sct_dmg_accum_duration_slider, ui)
|
||||
{
|
||||
events.push(SctDamageAccumDuration(new_val));
|
||||
}
|
||||
|
||||
Text::new(&format!("{:.2}", sct_dmg_accum_duration,))
|
||||
.right_from(state.ids.sct_dmg_accum_duration_slider, 8.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.graphics_for(state.ids.sct_dmg_accum_duration_slider)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_dmg_accum_duration_value, ui);
|
||||
|
||||
// Conditionally toggle incoming damage
|
||||
let show_inc_dmg = ToggleButton::new(
|
||||
self.global_state.settings.interface.sct_inc_dmg,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.sct_single_dmg_radio, 8.0)
|
||||
.down_from(state.ids.sct_dmg_accum_duration_slider, 8.0)
|
||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||
.set(state.ids.sct_show_batch_radio, ui);
|
||||
.set(state.ids.sct_show_inc_dmg_radio, ui);
|
||||
|
||||
if self.global_state.settings.interface.sct_damage_batch != show_sct_damage_batch {
|
||||
events.push(SctDamageBatch(
|
||||
!self.global_state.settings.interface.sct_damage_batch,
|
||||
if self.global_state.settings.interface.sct_inc_dmg != show_inc_dmg {
|
||||
events.push(SctIncomingDamage(
|
||||
!self.global_state.settings.interface.sct_inc_dmg,
|
||||
))
|
||||
}
|
||||
Text::new(self.localized_strings.get("hud.settings.cumulated_damage"))
|
||||
.right_from(state.ids.sct_show_batch_radio, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.sct_batched_dmg_radio)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_show_batch_text, ui);
|
||||
// Toggle Incoming Damage
|
||||
let show_sct_player_batch = !ToggleButton::new(
|
||||
!self.global_state.settings.interface.sct_player_batch,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.sct_show_batch_radio, 8.0)
|
||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||
.set(state.ids.sct_inc_dmg_radio, ui);
|
||||
|
||||
Text::new(self.localized_strings.get("hud.settings.incoming_damage"))
|
||||
.right_from(state.ids.sct_inc_dmg_radio, 10.0)
|
||||
.right_from(state.ids.sct_show_inc_dmg_radio, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.sct_inc_dmg_radio)
|
||||
.graphics_for(state.ids.sct_show_inc_dmg_radio)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_inc_dmg_text, ui);
|
||||
// Toggle Batched Incoming Damage
|
||||
let show_sct_player_batch = ToggleButton::new(
|
||||
show_sct_player_batch,
|
||||
.set(state.ids.sct_show_inc_dmg_text, ui);
|
||||
if self.global_state.settings.interface.sct_inc_dmg {
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.incoming_damage_accumulation_duration"),
|
||||
)
|
||||
.down_from(state.ids.sct_show_inc_dmg_radio, 8.0)
|
||||
.right_from(state.ids.sct_show_inc_dmg_radio, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_inc_dmg_accum_duration_text, ui);
|
||||
|
||||
if let Some(new_val) = ImageSlider::continuous(
|
||||
sct_inc_dmg_accum_duration,
|
||||
0.0,
|
||||
2.0,
|
||||
self.imgs.slider_indicator,
|
||||
self.imgs.slider,
|
||||
)
|
||||
.w_h(104.0, 22.0)
|
||||
.down_from(state.ids.sct_inc_dmg_accum_duration_text, 8.0)
|
||||
.track_breadth(12.0)
|
||||
.slider_length(10.0)
|
||||
.pad_track((5.0, 5.0))
|
||||
.set(state.ids.sct_inc_dmg_accum_duration_slider, ui)
|
||||
{
|
||||
events.push(SctIncomingDamageAccumDuration(new_val));
|
||||
}
|
||||
|
||||
Text::new(&format!("{:.2}", sct_inc_dmg_accum_duration,))
|
||||
.right_from(state.ids.sct_inc_dmg_accum_duration_slider, 8.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.graphics_for(state.ids.sct_inc_dmg_accum_duration_slider)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_inc_dmg_accum_duration_value, ui);
|
||||
}
|
||||
|
||||
// Round Damage
|
||||
let show_sct_damage_rounding = ToggleButton::new(
|
||||
self.global_state.settings.interface.sct_damage_rounding,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.sct_inc_dmg_radio, 8.0)
|
||||
.down_from(
|
||||
if self.global_state.settings.interface.sct_inc_dmg {
|
||||
state.ids.sct_inc_dmg_accum_duration_slider
|
||||
} else {
|
||||
state.ids.sct_show_inc_dmg_radio
|
||||
},
|
||||
8.0,
|
||||
)
|
||||
.x_align_to(state.ids.sct_show_inc_dmg_radio, Align::Start)
|
||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||
.set(state.ids.sct_batch_inc_radio, ui);
|
||||
.set(state.ids.sct_round_dmg_radio, ui);
|
||||
|
||||
if self.global_state.settings.interface.sct_player_batch != show_sct_player_batch {
|
||||
events.push(SctPlayerBatch(
|
||||
!self.global_state.settings.interface.sct_player_batch,
|
||||
if self.global_state.settings.interface.sct_damage_rounding != show_sct_damage_rounding
|
||||
{
|
||||
events.push(SctRoundDamage(
|
||||
!self.global_state.settings.interface.sct_damage_rounding,
|
||||
))
|
||||
}
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.cumulated_incoming_damage"),
|
||||
)
|
||||
.right_from(state.ids.sct_batch_inc_radio, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.sct_batch_inc_radio)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_batch_inc_text, ui);
|
||||
Text::new(self.localized_strings.get("hud.settings.round_damage"))
|
||||
.right_from(state.ids.sct_round_dmg_radio, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.sct_round_dmg_radio)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.sct_round_dmg_text, ui);
|
||||
}
|
||||
|
||||
// Speech bubbles
|
||||
Text::new(self.localized_strings.get("hud.settings.speech_bubble"))
|
||||
.down_from(
|
||||
if self.global_state.settings.interface.sct {
|
||||
state.ids.sct_batch_inc_radio
|
||||
state.ids.sct_round_dmg_radio
|
||||
} else {
|
||||
state.ids.sct_show_radio
|
||||
},
|
||||
@ -1062,6 +1114,46 @@ impl<'a> Widget for Interface<'a> {
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.always_show_bars_label, ui);
|
||||
|
||||
// Experience Numbers
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.experience_numbers"),
|
||||
)
|
||||
.down_from(state.ids.always_show_bars_button, 20.0)
|
||||
.font_size(self.fonts.cyri.scale(18))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.experience_numbers_title, ui);
|
||||
|
||||
// Acuumulate Experience Gained
|
||||
let accum_experience = ToggleButton::new(
|
||||
self.global_state.settings.interface.accum_experience,
|
||||
self.imgs.checkbox,
|
||||
self.imgs.checkbox_checked,
|
||||
)
|
||||
.w_h(18.0, 18.0)
|
||||
.down_from(state.ids.experience_numbers_title, 8.0)
|
||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||
.set(state.ids.accum_experience_button, ui);
|
||||
|
||||
if self.global_state.settings.interface.accum_experience != accum_experience {
|
||||
events.push(AccumExperience(
|
||||
!self.global_state.settings.interface.accum_experience,
|
||||
));
|
||||
}
|
||||
|
||||
Text::new(
|
||||
self.localized_strings
|
||||
.get("hud.settings.accumulate_experience"),
|
||||
)
|
||||
.right_from(state.ids.accum_experience_button, 10.0)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.graphics_for(state.ids.accum_experience_button)
|
||||
.color(TEXT_COLOR)
|
||||
.set(state.ids.accum_experience_text, ui);
|
||||
|
||||
// Reset the interface settings to the default settings
|
||||
if Button::image(self.imgs.button)
|
||||
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
|
||||
|
@ -284,7 +284,7 @@ impl ParticleMgr {
|
||||
| Outcome::ExpChange { .. }
|
||||
| Outcome::SkillPointGain { .. }
|
||||
| Outcome::ComboChange { .. }
|
||||
| Outcome::Damage { .. }
|
||||
| Outcome::HealthChange { .. }
|
||||
| Outcome::PoiseChange { .. }
|
||||
| Outcome::Utterance { .. }
|
||||
| Outcome::Glider { .. } => {},
|
||||
|
@ -1579,7 +1579,8 @@ impl PlayState for SessionState {
|
||||
for outcome in outcomes {
|
||||
self.scene
|
||||
.handle_outcome(&outcome, &scene_data, &mut global_state.audio);
|
||||
self.hud.handle_outcome(&outcome);
|
||||
self.hud
|
||||
.handle_outcome(&outcome, scene_data.client, global_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,8 +96,10 @@ pub enum Graphics {
|
||||
#[derive(Clone)]
|
||||
pub enum Interface {
|
||||
Sct(bool),
|
||||
SctPlayerBatch(bool),
|
||||
SctDamageBatch(bool),
|
||||
SctRoundDamage(bool),
|
||||
SctDamageAccumDuration(f32),
|
||||
SctIncomingDamage(bool),
|
||||
SctIncomingDamageAccumDuration(f32),
|
||||
SpeechBubbleSelf(bool),
|
||||
SpeechBubbleDarkMode(bool),
|
||||
SpeechBubbleIcon(bool),
|
||||
@ -134,6 +136,7 @@ pub enum Interface {
|
||||
MapShowPeaks(bool),
|
||||
MapShowBiomes(bool),
|
||||
MapShowVoxelMap(bool),
|
||||
AccumExperience(bool),
|
||||
|
||||
ResetInterfaceSettings,
|
||||
}
|
||||
@ -457,11 +460,17 @@ impl SettingsChange {
|
||||
Interface::Sct(sct) => {
|
||||
settings.interface.sct = sct;
|
||||
},
|
||||
Interface::SctPlayerBatch(sct_player_batch) => {
|
||||
settings.interface.sct_player_batch = sct_player_batch;
|
||||
Interface::SctRoundDamage(sct_round_damage) => {
|
||||
settings.interface.sct_damage_rounding = sct_round_damage;
|
||||
},
|
||||
Interface::SctDamageBatch(sct_damage_batch) => {
|
||||
settings.interface.sct_damage_batch = sct_damage_batch;
|
||||
Interface::SctDamageAccumDuration(sct_dmg_accum_duration) => {
|
||||
settings.interface.sct_dmg_accum_duration = sct_dmg_accum_duration;
|
||||
},
|
||||
Interface::SctIncomingDamage(sct_inc_dmg) => {
|
||||
settings.interface.sct_inc_dmg = sct_inc_dmg;
|
||||
},
|
||||
Interface::SctIncomingDamageAccumDuration(sct_inc_dmg_accum_duration) => {
|
||||
settings.interface.sct_inc_dmg_accum_duration = sct_inc_dmg_accum_duration;
|
||||
},
|
||||
Interface::SpeechBubbleSelf(sbdm) => {
|
||||
settings.interface.speech_bubble_self = sbdm;
|
||||
@ -559,6 +568,9 @@ impl SettingsChange {
|
||||
Interface::MapShowVoxelMap(map_show_voxel_map) => {
|
||||
settings.interface.map_show_voxel_map = map_show_voxel_map;
|
||||
},
|
||||
Interface::AccumExperience(accum_experience) => {
|
||||
settings.interface.accum_experience = accum_experience;
|
||||
},
|
||||
Interface::ResetInterfaceSettings => {
|
||||
// Reset Interface Settings
|
||||
let tmp = settings.interface.intro_show;
|
||||
|
@ -15,8 +15,10 @@ pub struct InterfaceSettings {
|
||||
pub toggle_chat: bool,
|
||||
pub toggle_hotkey_hints: bool,
|
||||
pub sct: bool,
|
||||
pub sct_player_batch: bool,
|
||||
pub sct_damage_batch: bool,
|
||||
pub sct_damage_rounding: bool,
|
||||
pub sct_dmg_accum_duration: f32,
|
||||
pub sct_inc_dmg: bool,
|
||||
pub sct_inc_dmg_accum_duration: f32,
|
||||
pub speech_bubble_self: bool,
|
||||
pub speech_bubble_dark_mode: bool,
|
||||
pub speech_bubble_icon: bool,
|
||||
@ -44,6 +46,7 @@ pub struct InterfaceSettings {
|
||||
pub minimap_show: bool,
|
||||
pub minimap_face_north: bool,
|
||||
pub minimap_zoom: f64,
|
||||
pub accum_experience: bool,
|
||||
}
|
||||
|
||||
impl Default for InterfaceSettings {
|
||||
@ -55,8 +58,10 @@ impl Default for InterfaceSettings {
|
||||
toggle_chat: true,
|
||||
toggle_hotkey_hints: true,
|
||||
sct: true,
|
||||
sct_player_batch: false,
|
||||
sct_damage_batch: false,
|
||||
sct_damage_rounding: false,
|
||||
sct_dmg_accum_duration: 0.45,
|
||||
sct_inc_dmg: true,
|
||||
sct_inc_dmg_accum_duration: 0.45,
|
||||
speech_bubble_self: true,
|
||||
speech_bubble_dark_mode: false,
|
||||
speech_bubble_icon: true,
|
||||
@ -84,6 +89,7 @@ impl Default for InterfaceSettings {
|
||||
minimap_show: true,
|
||||
minimap_face_north: true,
|
||||
minimap_zoom: 160.0,
|
||||
accum_experience: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user