mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'master' of gitlab.com:veloren/veloren into sharp/small-fixes
This commit is contained in:
commit
f8376fd5dc
31
CHANGELOG.md
31
CHANGELOG.md
@ -9,6 +9,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Added context-sensitive crosshair
|
||||
|
||||
### Changed
|
||||
|
||||
- Improved camera aiming
|
||||
|
||||
### Removed
|
||||
|
||||
## [0.6.0] - 2020-05-16
|
||||
|
||||
### Added
|
||||
|
||||
- Added music system
|
||||
- Added zoomable and rotatable minimap
|
||||
- Added rotating orientation marker to main-map
|
||||
@ -73,6 +85,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Added tab completion in chat for player names and chat commands
|
||||
- Added server persistence for character stats
|
||||
- Added a popup when setting your character's waypoint
|
||||
- Added dungeon arenas
|
||||
- Added dungeon bosses and rare boss loot
|
||||
- Added 2 sets of armour. One Steel and one Leather.
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
@ -96,7 +112,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Removed
|
||||
|
||||
## [0.5.0] - 2019-01-31
|
||||
## [0.5.0] - 2020-01-31
|
||||
|
||||
### Added
|
||||
|
||||
@ -260,9 +276,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
_0.1.0 was part of the legacy engine_
|
||||
|
||||
[unreleased]: https://gitlab.com/veloren/veloren/compare?from=v0.5.0&to=master
|
||||
[0.0.5]: https://gitlab.com/veloren/veloren/compare?from=v0.4.0&to=v0.5.0
|
||||
[0.0.4]: https://gitlab.com/veloren/veloren/compare?from=v0.3.0&to=v0.4.0
|
||||
[0.0.3]: https://gitlab.com/veloren/veloren/compare?from=v0.2.0&to=v0.3.0
|
||||
[0.0.2]: https://gitlab.com/veloren/veloren/compare?from=7d17f8b67a2a6d5aa00730f028cedc430fd5075a&to=v0.2.0
|
||||
[0.0.1]: https://gitlab.com/veloren/game
|
||||
[unreleased]: https://gitlab.com/veloren/veloren/compare?from=v0.6.0&to=master
|
||||
[0.6.0]: https://gitlab.com/veloren/veloren/compare?from=v0.5.0&to=v0.6.0
|
||||
[0.5.0]: https://gitlab.com/veloren/veloren/compare?from=v0.4.0&to=v0.5.0
|
||||
[0.4.0]: https://gitlab.com/veloren/veloren/compare?from=v0.3.0&to=v0.4.0
|
||||
[0.3.0]: https://gitlab.com/veloren/veloren/compare?from=v0.2.0&to=v0.3.0
|
||||
[0.2.0]: https://gitlab.com/veloren/veloren/compare?from=7d17f8b67a2a6d5aa00730f028cedc430fd5075a&to=v0.2.0
|
||||
[0.1.0]: https://gitlab.com/veloren/game
|
||||
|
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -4959,7 +4959,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veloren-chat-cli"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"log 0.4.8",
|
||||
"pretty_env_logger",
|
||||
@ -4969,7 +4969,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veloren-client"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"authc",
|
||||
"byteorder 1.3.4",
|
||||
@ -4988,7 +4988,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veloren-common"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"authc",
|
||||
"bincode",
|
||||
@ -5020,7 +5020,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veloren-server"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"authc",
|
||||
"chrono",
|
||||
@ -5051,7 +5051,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veloren-server-cli"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"log 0.4.8",
|
||||
"pretty_env_logger",
|
||||
@ -5061,7 +5061,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veloren-voxygen"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"authc",
|
||||
"backtrace",
|
||||
@ -5113,7 +5113,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "veloren-world"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"arr_macro",
|
||||
"bincode",
|
||||
|
@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img alt="Veloren logo on a screenshot" src="https://i.redd.it/balynnef4x531.png">
|
||||
<img alt="Veloren logo on a screenshot" src="https://cdn.discordapp.com/attachments/541307708146581519/712295605170602075/logo.png">
|
||||
</p>
|
||||
|
||||
[![pipeline status](https://gitlab.com/veloren/veloren/badges/master/pipeline.svg)](https://gitlab.com/veloren/veloren/commits/master)
|
||||
@ -36,7 +36,7 @@ This will be needed to play on auth-enabled servers, including the official serv
|
||||
Currently we provide 64-bit builds for Linux and Windows which can be downloaded on the official website:
|
||||
[https://www.veloren.net](https://veloren.net/welcome)
|
||||
|
||||
*Note: Mac and 32-bit systems are supported but you need to [compile the game for them yourself](https://book.veloren.net/compile/index.html).*
|
||||
_Note: Mac and 32-bit systems are supported but you need to [compile the game for them yourself](https://book.veloren.net/compile/index.html)._
|
||||
|
||||
Due to rapid developement stable versions become outdated fast and might be **incompatible with the public server**.
|
||||
|
||||
@ -59,6 +59,7 @@ If you want to compile Veloren yourself, take a look at the [How to Compile Guid
|
||||
[AUR latest master](https://aur.archlinux.org/packages/veloren-git): `yay -Syu veloren-git`
|
||||
|
||||
## F.A.Q.
|
||||
|
||||
### **Q:** How is this game licensed?
|
||||
|
||||
**A:** **It's free to play, modify and distribute. Forever.** Since it is a community project, we decided to license it under the **GNU GPL 3.0** license which means it will always stay free and open source.
|
||||
|
8
assets/common/items/armor/belt/leather_2.ron
Normal file
8
assets/common/items/armor/belt/leather_2.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Leather Belt",
|
||||
description: "A belt made from simple leather.",
|
||||
kind: Armor(
|
||||
kind: Belt(Leather2),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/belt/steel_0.ron
Normal file
8
assets/common/items/armor/belt/steel_0.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Steel Belt",
|
||||
description: "A belt made from Steel.",
|
||||
kind: Armor(
|
||||
kind: Belt(Steel0),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/chest/leather_2.ron
Normal file
8
assets/common/items/armor/chest/leather_2.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Leather Cuirass",
|
||||
description: "A cuirass made of simple leather",
|
||||
kind: Armor(
|
||||
kind: Chest(Leather2),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/chest/steel_0.ron
Normal file
8
assets/common/items/armor/chest/steel_0.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Steel Cuirass",
|
||||
description: "A cuirass of steel plate",
|
||||
kind: Armor(
|
||||
kind: Chest(Steel0),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/foot/leather_2.ron
Normal file
8
assets/common/items/armor/foot/leather_2.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Leather Boots",
|
||||
description: "Boots made of simple leather",
|
||||
kind: Armor(
|
||||
kind: Foot(Leather2),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/foot/steel_0.ron
Normal file
8
assets/common/items/armor/foot/steel_0.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Steel Boots",
|
||||
description: "Boots plated in steel",
|
||||
kind: Armor(
|
||||
kind: Foot(Steel0),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/hand/leather_2.ron
Normal file
8
assets/common/items/armor/hand/leather_2.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Leather Gloves",
|
||||
description: "Gloves made of simple leather",
|
||||
kind: Armor(
|
||||
kind: Hand(Leather2),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/hand/steel_0.ron
Normal file
8
assets/common/items/armor/hand/steel_0.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Steel Gauntlets",
|
||||
description: "Gauntlets made of steel",
|
||||
kind: Armor(
|
||||
kind: Hand(Steel0),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/pants/leather_2.ron
Normal file
8
assets/common/items/armor/pants/leather_2.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Leather Leg Armour",
|
||||
description: "Leg armour made of simple leather",
|
||||
kind: Armor(
|
||||
kind: Pants(Leather2),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/pants/steel_0.ron
Normal file
8
assets/common/items/armor/pants/steel_0.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Steel Chausses",
|
||||
description: "Leg armour made of steel plates",
|
||||
kind: Armor(
|
||||
kind: Pants(Steel0),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/shoulder/leather_2.ron
Normal file
8
assets/common/items/armor/shoulder/leather_2.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Leather Shoulder Pad",
|
||||
description: "A simple shoulder pad made of leather",
|
||||
kind: Armor(
|
||||
kind: Shoulder(Leather2),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
8
assets/common/items/armor/shoulder/steel_0.ron
Normal file
8
assets/common/items/armor/shoulder/steel_0.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Steel Shoulder Pad",
|
||||
description: "A simple shoulder pad made of steel",
|
||||
kind: Armor(
|
||||
kind: Shoulder(Steel0),
|
||||
stats: (20),
|
||||
),
|
||||
)
|
12
assets/common/items/armor/starter/lantern.ron
Normal file
12
assets/common/items/armor/starter/lantern.ron
Normal file
@ -0,0 +1,12 @@
|
||||
Item(
|
||||
name: "Black Lantern",
|
||||
description: "Used by city guards.",
|
||||
kind: Lantern(
|
||||
(
|
||||
kind: Black0,
|
||||
color: (r: 255, g: 190, b: 75),
|
||||
strength_thousandths: 3000,
|
||||
flicker_thousandths: 300,
|
||||
),
|
||||
),
|
||||
)
|
12
assets/common/items/boss_drops/lantern.ron
Normal file
12
assets/common/items/boss_drops/lantern.ron
Normal file
@ -0,0 +1,12 @@
|
||||
Item(
|
||||
name: "Magic Lantern",
|
||||
description: "Illuminates even the darkest dungeon\nA great monster was slain for this item",
|
||||
kind: Lantern(
|
||||
(
|
||||
kind: Blue0,
|
||||
color: (r: 220, g: 220, b: 255),
|
||||
strength_thousandths: 6500,
|
||||
flicker_thousandths: 300,
|
||||
),
|
||||
),
|
||||
)
|
12
assets/common/items/boss_drops/potions.ron
Normal file
12
assets/common/items/boss_drops/potions.ron
Normal file
@ -0,0 +1,12 @@
|
||||
Item(
|
||||
name: "Powerful Potion",
|
||||
description: "Restores 100 Health\nA great monster was slain for this item\n\n<Right-Click to use>",
|
||||
kind: Consumable(
|
||||
kind: Potion,
|
||||
effect: Health((
|
||||
amount: 100,
|
||||
cause: Item,
|
||||
)),
|
||||
amount: 15,
|
||||
),
|
||||
)
|
8
assets/common/items/boss_drops/xp_potion.ron
Normal file
8
assets/common/items/boss_drops/xp_potion.ron
Normal file
@ -0,0 +1,8 @@
|
||||
Item(
|
||||
name: "Potion of Skill",
|
||||
description: "Provides 250 XP to the drinker\n\n<Right-Click to use>",
|
||||
kind: Consumable(
|
||||
kind: Potion,
|
||||
effect: Xp(250),
|
||||
),
|
||||
)
|
@ -1,5 +1,14 @@
|
||||
// TODO: Re-add tunes that are not fitting general outside day/night situations
|
||||
|
||||
(
|
||||
tracks: [
|
||||
(
|
||||
title: "Into The Dark Forest",
|
||||
path: "voxygen.audio.soundtrack.into_the_dark_forest",
|
||||
length: 184.0,
|
||||
timing: Some(Night),
|
||||
artist: "Aeronic",
|
||||
),
|
||||
(
|
||||
title: "Field Grazing",
|
||||
path: "voxygen.audio.soundtrack.field_grazing",
|
||||
@ -14,13 +23,13 @@
|
||||
timing: Some(Night),
|
||||
artist: "Aeronic",
|
||||
),
|
||||
(
|
||||
title: "Snowtop Volume",
|
||||
/*(
|
||||
title: "Snowtop Volume", //Snow Region
|
||||
path: "voxygen.audio.soundtrack.snowtop_volume",
|
||||
length: 89.0,
|
||||
timing: Some(Day),
|
||||
artist: "Aeronic",
|
||||
),
|
||||
),*/
|
||||
(
|
||||
title: "Mineral Deposits",
|
||||
path: "voxygen.audio.soundtrack.mineral_deposits",
|
||||
@ -42,13 +51,13 @@
|
||||
timing: Some(Night),
|
||||
artist: "Aeronic",
|
||||
),
|
||||
(
|
||||
title: "Rest Assured",
|
||||
/*(
|
||||
title: "Rest Assured", // Town/Shop
|
||||
path: "voxygen.audio.soundtrack.rest_assured",
|
||||
length: 185.0,
|
||||
timing: Some(Day),
|
||||
artist: "badbbad",
|
||||
),
|
||||
),*/
|
||||
(
|
||||
title: "Just The Beginning",
|
||||
path: "voxygen.audio.soundtrack.just_the_beginning",
|
||||
@ -70,13 +79,13 @@
|
||||
timing: Some(Night),
|
||||
artist: "badbbad",
|
||||
),
|
||||
(
|
||||
/*( // Dungeon
|
||||
title: "Down The Rabbit Hole",
|
||||
path: "voxygen.audio.soundtrack.down_the_rabbit_hole",
|
||||
length: 244.0,
|
||||
timing: Some(Night),
|
||||
artist: "badbbad",
|
||||
),
|
||||
),*/
|
||||
(
|
||||
title: "Between The Fairies",
|
||||
path: "voxygen.audio.soundtrack.between_the_fairies",
|
||||
|
BIN
assets/voxygen/audio/soundtrack/into_the_dark_forest.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/into_the_dark_forest.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/background/bg_1.png
(Stored with Git LFS)
BIN
assets/voxygen/background/bg_1.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/background/bg_12.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/background/bg_12.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/background/bg_13.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/background/bg_13.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/background/bg_14.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/background/bg_14.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/background/bg_15.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/background/bg_15.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/background/bg_16.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/background/bg_16.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/background/bg_3.png
(Stored with Git LFS)
BIN
assets/voxygen/background/bg_3.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/background/bg_main.png
(Stored with Git LFS)
BIN
assets/voxygen/background/bg_main.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/help.png
(Stored with Git LFS)
BIN
assets/voxygen/element/help.png
(Stored with Git LFS)
Binary file not shown.
@ -54,7 +54,7 @@ VoxygenLocalization(
|
||||
"common.controls": "Tastenbelegung",
|
||||
"common.video": "Grafik",
|
||||
"common.sound": "Audio",
|
||||
"common.resume": "Weiter",
|
||||
"common.resume": "Zurück",
|
||||
"common.characters": "Charaktere",
|
||||
"common.close": "Schließen",
|
||||
"common.yes": "Ja",
|
||||
@ -136,6 +136,7 @@ eurer erstellen Charaktere gespeichert."#,
|
||||
"main.login.already_logged_in": "Ihr seid bereits eingelogged",
|
||||
"main.login.network_error": "Netzwerkfehler",
|
||||
"main.login.failed_sending_request": "Authentifizierung fehlgeschlagen",
|
||||
"main.login.invalid_character": "Ungültiger Charakter",
|
||||
"main.login.client_crashed": "Client abgestürzt",
|
||||
|
||||
/// End Main screen section
|
||||
@ -146,6 +147,7 @@ eurer erstellen Charaktere gespeichert."#,
|
||||
"hud.show_tips": "Tips zeigen.",
|
||||
"hud.quests": "Quests",
|
||||
"hud.you_died": "Ihr seid gestorben.",
|
||||
"hud.waypoint_saved": "Wegpunkt gesichert",
|
||||
|
||||
"hud.press_key_to_show_keybindings_fmt": "Drückt {key} um die Tastenbelegung zu zeigen",
|
||||
"hud.press_key_to_show_debug_info_fmt": "Drückt {key} um die Debug-Info zu zeigen",
|
||||
@ -173,7 +175,7 @@ Sammelt diese mit Rechts-Klick auf.
|
||||
|
||||
Um diese zu nutzen öffnet euer Inventar mit 'B'.
|
||||
|
||||
Doppelklickt den Gegenstand in eurer Tasche, um dieses zu nutzen.
|
||||
Doppelklickt den Gegenstand in eurer Tasche, um diesen zu nutzen.
|
||||
|
||||
Um Items wegzuwerfen klickt sie einmal im Inventar an
|
||||
|
||||
@ -182,7 +184,7 @@ und klickt dann außerhalb der Tasche.
|
||||
|
||||
Die Nächte in Veloren können sehr dunkel werden.
|
||||
|
||||
Um eure Laterne anzuzünden gebt /lantern in den Chat ein.
|
||||
Drückt 'G' um eure Laterne einzuschalten.
|
||||
|
||||
|
||||
Ihr wollt endlich spielen und dafür euren Cursor befreien,
|
||||
@ -317,6 +319,7 @@ Viel Spaß in der Welt von Veloren, Abenteurer!"#,
|
||||
"gameinput.climb": "Klettern",
|
||||
"gameinput.climbdown": "Runter klettern",
|
||||
"gameinput.wallleap": "Wandsprung",
|
||||
"gameinput.togglelantern": "Laterne ein-/ausschalten",
|
||||
"gameinput.mount": "Aufsteigen",
|
||||
"gameinput.enter": "Betreten",
|
||||
"gameinput.command": "Befehl",
|
||||
@ -336,11 +339,14 @@ Viel Spaß in der Welt von Veloren, Abenteurer!"#,
|
||||
/// End GameInput section
|
||||
|
||||
/// Start chracter selection section
|
||||
"char_selection.loading_characters": "Lade Charaktere...",
|
||||
"char_selection.delete_permanently": "Diesen Charakter unwiderruflich löschen?",
|
||||
"char_selection.deleting_character": "Lösche Charakter...",
|
||||
"char_selection.change_server": "Server wechseln.",
|
||||
"char_selection.enter_world": "Betreten",
|
||||
"char_selection.logout": "Logout",
|
||||
"char_selection.logout": "Ausloggen",
|
||||
"char_selection.create_charater": "Charakter erstellen",
|
||||
"char_selection.creating_character": "Erstelle Charakter...",
|
||||
"char_selection.character_creation": "Charakter Erstellung",
|
||||
"char_selection.create_new_charater": "Neuen Charakter erstellen",
|
||||
|
||||
@ -356,6 +362,7 @@ Viel Spaß in der Welt von Veloren, Abenteurer!"#,
|
||||
"char_selection.skin": "Hautton",
|
||||
"char_selection.eyebrows": "Augenbrauen",
|
||||
"char_selection.accessories": "Accessoires",
|
||||
"char_selection.create_info_name": "Euer Charakter braucht einen Namen!",
|
||||
/// End chracter selection section
|
||||
/// Start character window section
|
||||
"character_window.character_name": "Charakter",
|
||||
|
@ -182,7 +182,7 @@ Throw them away by clicking them once and clicking outside of the bag
|
||||
|
||||
Nights can get pretty dark in Veloren.
|
||||
|
||||
Equip your lantern and light it by pressing G.
|
||||
Light your lantern by pressing 'G'
|
||||
|
||||
|
||||
Want to free your cursor to close this window? Press TAB!
|
||||
@ -351,7 +351,7 @@ Enjoy your stay in the World of Veloren."#,
|
||||
|
||||
"char_selection.human_default": "Human Default",
|
||||
"char_selection.level_fmt": "Level {level_nb}",
|
||||
"char_selection.uncanny_valley": "Uncanny Valley",
|
||||
"char_selection.uncanny_valley": "Wilderness",
|
||||
"char_selection.plains_of_uncertainty": "Plains of Uncertainty",
|
||||
"char_selection.beard": "Beard",
|
||||
"char_selection.hair_style": "Hair Style",
|
||||
@ -361,6 +361,7 @@ Enjoy your stay in the World of Veloren."#,
|
||||
"char_selection.skin": "Skin",
|
||||
"char_selection.eyebrows": "Eyebrows",
|
||||
"char_selection.accessories": "Accessories",
|
||||
"char_selection.create_info_name": "Your Character needs a name!",
|
||||
|
||||
/// End chracter selection section
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
VoxygenLocalization(
|
||||
metadata: (
|
||||
language_name: "Italiano",
|
||||
language_identifier: "it",
|
||||
language_identifier: "it_IT",
|
||||
),
|
||||
convert_utf8_to_ascii: false,
|
||||
fonts: {
|
369
assets/voxygen/i18n/ru_RU.ron
Normal file
369
assets/voxygen/i18n/ru_RU.ron
Normal file
@ -0,0 +1,369 @@
|
||||
/// Localization for "global" Russian
|
||||
VoxygenLocalization(
|
||||
metadata: (
|
||||
language_name: "Русский",
|
||||
language_identifier: "ru_RU",
|
||||
),
|
||||
convert_utf8_to_ascii: false,
|
||||
fonts: {
|
||||
"opensans": Font (
|
||||
asset_key: "voxygen.font.OpenSans-Regular",
|
||||
scale_ratio: 1.0,
|
||||
),
|
||||
"metamorph": Font (
|
||||
asset_key: "voxygen.font.Metamorphous-Regular",
|
||||
scale_ratio: 1.0,
|
||||
),
|
||||
"alkhemi": Font (
|
||||
asset_key: "voxygen.font.Alkhemikal",
|
||||
scale_ratio: 1.0,
|
||||
),
|
||||
"wizard": Font (
|
||||
asset_key: "voxygen.font.wizard",
|
||||
scale_ratio: 1.0,
|
||||
),
|
||||
"cyri": Font (
|
||||
asset_key: "voxygen.font.haxrcorp_4089_cyrillic_altgr_extended",
|
||||
scale_ratio: 1.0,
|
||||
),
|
||||
},
|
||||
string_map: {
|
||||
/// Start Common section
|
||||
// Texts used in multiple locations with the same formatting
|
||||
"common.username": "Имя пользователя",
|
||||
"common.singleplayer": "Одиночная игра",
|
||||
"common.multiplayer": "Мультиплеер",
|
||||
"common.servers": "Сервера",
|
||||
"common.quit": "Выход",
|
||||
"common.settings": "Настройки",
|
||||
"common.languages": "Язык",
|
||||
"common.interface": "Интерфейс",
|
||||
"common.gameplay": "Геймплей",
|
||||
"common.controls": "Управление",
|
||||
"common.video": "Видео",
|
||||
"common.sound": "Звук",
|
||||
"common.resume": "Продолжить",
|
||||
"common.characters": "Персонажи",
|
||||
"common.close": "Закрыть",
|
||||
"common.yes": "Да",
|
||||
"common.no": "Нет",
|
||||
"common.back": "Назад",
|
||||
"common.create": "Создать",
|
||||
"common.okay": "Хорошо",
|
||||
"common.accept": "Принять",
|
||||
"common.disclaimer": "Дисклеймер",
|
||||
"common.cancel": "Отмена",
|
||||
"common.none": "Нет",
|
||||
"common.error": "Ошибка",
|
||||
"common.fatal_error": "Критическая ошибка",
|
||||
|
||||
// Message when connection to the server is lost
|
||||
"common.connection_lost": r#"Соединение потеряно!
|
||||
Сервер перезагрузился?
|
||||
Клиент обновлен до последней версии?"#,
|
||||
|
||||
|
||||
"common.races.orc": "Орк",
|
||||
"common.races.human": "Человек",
|
||||
"common.races.dwarf": "Дварф",
|
||||
"common.races.elf": "Эльф",
|
||||
"common.races.undead": "Нежить",
|
||||
"common.races.danari": "Данари",
|
||||
|
||||
"common.weapons.axe": "Топор",
|
||||
"common.weapons.sword": "Меч",
|
||||
"common.weapons.staff": "Посох",
|
||||
"common.weapons.bow": "Лук",
|
||||
"common.weapons.hammer": "Молот",
|
||||
/// End Common section
|
||||
|
||||
|
||||
/// Start Main screen section
|
||||
"main.connecting": "Подключение",
|
||||
"main.creating_world": "Создание мира",
|
||||
|
||||
// Welcome notice that appears the first time Veloren is started
|
||||
"main.notice": r#"Добро пожаловать в Veloren-Alpha!
|
||||
|
||||
Прежде чем начать веселье, прими во внимание следующие вещи:
|
||||
|
||||
- Это очень ранняя альфа. Тут есть баги, крайне незавершенный геймплей, неотполированные механики и отсутсвующие фичи.
|
||||
- Если у вас есть конструктивный фидбек или сообщение об ошибке, вы можете связаться с нами через Reddit, GitLab или наш Discord-сервер.
|
||||
- Veloren лицензирован GPL 3 open-source licence. Это означает, игра бесплатна, ее можно модифицировать и переделывать на свой вкус (при условии, что готовая работа тоже лицензирована GPL 3).
|
||||
- Veloren - некоммерческий проект, каждый работает над ним добровольно.
|
||||
Если тебе нравится, что ты видишь, милости просим присоедниться к команде разработчиков или худождественной команде!
|
||||
- 'Воксельная РПГ' - самобытный жанр. ФПС тоже привыкли называть 'Клонами Дума'.
|
||||
|
||||
Как и они, мы пытаемся построить нишу. Эта игра не клон, ее развитие в будущем будет отличаться от существующих игр.
|
||||
|
||||
Спасибо за прочтение, мы надеемся, вам понравится игра!
|
||||
|
||||
~ Команда разработчиков Veloren"#,
|
||||
|
||||
|
||||
// Login process description
|
||||
"main.login_process": r#"Информация по входу:
|
||||
|
||||
Если у вас есть проблемы со входом:
|
||||
|
||||
Обратите внимание, что теперь вам нужен аккаунт
|
||||
играть на серверах с включенной аутентификацией.
|
||||
|
||||
Вы можете создать аккаунт тут:
|
||||
|
||||
https://account.veloren.net."#,
|
||||
"main.login.server_not_found": "Сервер не найден",
|
||||
"main.login.authentication_error": "Ошибка аутентификации на сервер",
|
||||
"main.login.server_full": "Сервер полон",
|
||||
"main.login.untrusted_auth_server": "Аутентификация не пройдена",
|
||||
"main.login.outdated_client_or_server": "ServerWentMad: Возможно, версии несовместимы. Проверьте наличие обновлений.",
|
||||
"main.login.timeout": "Timeout: Сервер не ответил вовремя. (Перегрузка или проблемы с сетью).",
|
||||
"main.login.server_shut_down": "Сервер выключен",
|
||||
"main.login.already_logged_in": "Вы уже вошли на сервер.",
|
||||
"main.login.network_error": "Ошибка сети",
|
||||
"main.login.failed_sending_request": "Запрос аутентификации провален",
|
||||
"main.login.client_crashed": "Клиент вылетел",
|
||||
|
||||
/// End Main screen section
|
||||
|
||||
|
||||
/// Start HUD Section
|
||||
"hud.do_not_show_on_startup": "Не показывать это при запуске",
|
||||
"hud.show_tips": "Показать советы",
|
||||
"hud.quests": "Квесты",
|
||||
"hud.you_died": "Вы мертвы",
|
||||
|
||||
"hud.press_key_to_show_keybindings_fmt": "Нажмите {key}, чтобы посмотреть раскладку",
|
||||
"hud.press_key_to_show_debug_info_fmt": "Нажмите {key}, чтобы показать панель отладки",
|
||||
"hud.press_key_to_toggle_keybindings_fmt": "Нажмите {key}, чтобы привязать клавишу",
|
||||
"hud.press_key_to_toggle_debug_info_fmt": "Нажмите {key}, чтобы переназначить панель отладки",
|
||||
|
||||
// Respawn message
|
||||
"hud.press_key_to_respawn": r#"Нажмите {key}, чтобы возродиться на последнем костре, который вы посетили."#,
|
||||
|
||||
// Welcome message
|
||||
"hud.welcome": r#"Добро пожаловать в Veloren-Alpha!,
|
||||
|
||||
|
||||
Немного советов перед тем началом игры:
|
||||
|
||||
|
||||
НАИБОЛЕЕ ВАЖНО: Чтобы установить точку спауна, напишите /waypoint в чат.
|
||||
|
||||
Это возможно, даже если вы уже мертвы!
|
||||
|
||||
|
||||
Нажмите F1, чтобы увидеть доступые команды.
|
||||
|
||||
Напишите /help, чтобы увидеть команды чата.
|
||||
|
||||
|
||||
В мире есть сундуки и другие рандомно генерируемые объекты!
|
||||
|
||||
Нажмите ПКМ, чтобы собрать их.
|
||||
|
||||
Чтобы использовать то, что мы нашли в сундуках, откройте свой инвентарь 'B'.
|
||||
|
||||
Двойной клик на предмет в инвентаре использует или экипирует его.
|
||||
|
||||
Чтобы выкинуть их, кликните на предмет, а потом кликите вне инвентаря.
|
||||
|
||||
|
||||
Ночи в Veloren могут быть довольно темными.
|
||||
|
||||
Зажгите свой фонарь, написав /lantern в чат.
|
||||
|
||||
|
||||
Хотите увидеть курсор, чтобы закрыть это окно? Нажмите TAB!
|
||||
|
||||
|
||||
Наслаждайтесь миром Veloren."#,
|
||||
|
||||
|
||||
// Inventory
|
||||
"hud.bag.inventory": "Инвентарь",
|
||||
"hud.bag.stats_title": "Статы",
|
||||
"hud.bag.exp": "Опыт",
|
||||
"hud.bag.armor": "Броня",
|
||||
"hud.bag.stats": "Статы",
|
||||
"hud.bag.head": "Голова",
|
||||
"hud.bag.neck": "Шея",
|
||||
"hud.bag.tabard": "Накидка",
|
||||
"hud.bag.shoulders": "Плечи",
|
||||
"hud.bag.chest": "Нагрудник",
|
||||
"hud.bag.hands": "Руки",
|
||||
"hud.bag.lantern": "Фонарь",
|
||||
"hud.bag.belt": "Пояс",
|
||||
"hud.bag.ring": "Кольцо",
|
||||
"hud.bag.back": "Спина",
|
||||
"hud.bag.legs": "Ноги",
|
||||
"hud.bag.feet": "Ботинки",
|
||||
"hud.bag.mainhand": "Главная рука",
|
||||
"hud.bag.offhand": "Второстепенная рука",
|
||||
|
||||
|
||||
// Map and Questlog
|
||||
"hud.map.map_title": "Карта",
|
||||
"hud.map.qlog_title": "Квесты",
|
||||
|
||||
// Settings
|
||||
"hud.settings.general": "Общие",
|
||||
"hud.settings.none": "Нет",
|
||||
"hud.settings.press_behavior.toggle": "Переключить",
|
||||
"hud.settings.press_behavior.hold": "Держать",
|
||||
"hud.settings.help_window": "Окно помощи",
|
||||
"hud.settings.debug_info": "Панель отладки",
|
||||
"hud.settings.tips_on_startup": "Советы на старте",
|
||||
"hud.settings.ui_scale": "Размер интерфейса",
|
||||
"hud.settings.relative_scaling": "Относительное масштабирование",
|
||||
"hud.settings.custom_scaling": "Пользовательское масштабирование",
|
||||
"hud.settings.crosshair": "Перекрестие",
|
||||
"hud.settings.transparency": "Прозрачность",
|
||||
"hud.settings.hotbar": "Хотбар",
|
||||
"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": "Проценты",
|
||||
"hud.settings.chat": "Чат",
|
||||
"hud.settings.background_transparency": "Прозрачность заднего фона",
|
||||
|
||||
"hud.settings.pan_sensitivity": "Чувствительность камеры",
|
||||
"hud.settings.zoom_sensitivity": "Чувствительность зума",
|
||||
"hud.settings.invert_scroll_zoom": "Инвертировать прокрутку зума",
|
||||
"hud.settings.invert_mouse_y_axis": "Инвертировать ось Y",
|
||||
"hud.settings.free_look_behavior": "Настройка свободной камеры",
|
||||
|
||||
"hud.settings.view_distance": "Дальность прорисовки",
|
||||
"hud.settings.maximum_fps": "Максимум FPS",
|
||||
"hud.settings.fov": "Поле зрения (градусы)",
|
||||
"hud.settings.gamma": "Гамма",
|
||||
"hud.settings.antialiasing_mode": "Сглаживание",
|
||||
"hud.settings.cloud_rendering_mode": "Рендер облаков",
|
||||
"hud.settings.fluid_rendering_mode": "Рендер жидкостей",
|
||||
"hud.settings.fluid_rendering_mode.cheap": "Низко",
|
||||
"hud.settings.fluid_rendering_mode.shiny": "Высоко",
|
||||
"hud.settings.cloud_rendering_mode.regular": "Обычно",
|
||||
"hud.settings.fullscreen": "Полный экран",
|
||||
"hud.settings.save_window_size": "Сохранить размер окна",
|
||||
|
||||
"hud.settings.music_volume": "Громкость музыки",
|
||||
"hud.settings.sound_effect_volume": "Громкость звуковых эффектов",
|
||||
"hud.settings.audio_device": "Устройство аудио",
|
||||
|
||||
"hud.settings.awaitingkey": "Нажми клавишу...",
|
||||
|
||||
"hud.social": "Социальное",
|
||||
"hud.social.online": "Онлайн",
|
||||
"hud.social.friends": "Друзья",
|
||||
"hud.social.not_yet_available": "Пока недоступно",
|
||||
"hud.social.faction": "Фракция",
|
||||
"hud.social.play_online_fmt": "{nb_player} игрок(ов) онлайн",
|
||||
|
||||
"hud.spell": "Заклинание",
|
||||
|
||||
"hud.free_look_indicator": "Свободная камера активна",
|
||||
|
||||
/// End HUD section
|
||||
|
||||
|
||||
/// Start GameInput section
|
||||
|
||||
"gameinput.primary": "Основная атака",
|
||||
"gameinput.secondary": "Второстепенная атака/Блок/Прицел",
|
||||
"gameinput.slot1": "Быстрый слот 1",
|
||||
"gameinput.slot2": "Быстрый слот 2",
|
||||
"gameinput.slot3": "Быстрый слот 3",
|
||||
"gameinput.slot4": "Быстрый слот 4",
|
||||
"gameinput.slot5": "Быстрый слот 5",
|
||||
"gameinput.slot6": "Быстрый слот 6",
|
||||
"gameinput.slot7": "Быстрый слот 7",
|
||||
"gameinput.slot8": "Быстрый слот 8",
|
||||
"gameinput.slot9": "Быстрый слот 9",
|
||||
"gameinput.slot10": "Быстрый слот 10",
|
||||
"gameinput.swaploadout": "Сменить снаряжение",
|
||||
"gameinput.togglecursor": "Отображать курсор курсор",
|
||||
"gameinput.help": "Отображать окно помощи",
|
||||
"gameinput.toggleinterface": "Отображать интерфейс",
|
||||
"gameinput.toggledebug": "Отображать FPS и экран отладки",
|
||||
"gameinput.screenshot": "Сделать скриншот",
|
||||
"gameinput.toggleingameui": "Отображать неймтеги",
|
||||
"gameinput.fullscreen": "Включить полный экран",
|
||||
"gameinput.moveforward": "Двигаться вперед",
|
||||
"gameinput.moveleft": "Двигаться влево",
|
||||
"gameinput.moveright": "Двигаться вправо",
|
||||
"gameinput.moveback": "Двигаться назад",
|
||||
"gameinput.jump": "Прыжок",
|
||||
"gameinput.glide": "Глайдер",
|
||||
"gameinput.roll": "Кувырок",
|
||||
"gameinput.climb": "Карабкаться",
|
||||
"gameinput.climbdown": "Карабкаться вниз",
|
||||
"gameinput.wallleap": "Прыжок от стены",
|
||||
"gameinput.mount": "Оседлать",
|
||||
"gameinput.enter": "Войти",
|
||||
"gameinput.command": "Командовать",
|
||||
"gameinput.escape": "Выйти",
|
||||
"gameinput.map": "Карта",
|
||||
"gameinput.bag": "Рюкзак",
|
||||
"gameinput.social": "Социальное",
|
||||
"gameinput.sit": "Сесть",
|
||||
"gameinput.spellbook": "Заклинания",
|
||||
"gameinput.settings": "Найстройки",
|
||||
"gameinput.respawn": "Возродиться",
|
||||
"gameinput.charge": "Зарядить",
|
||||
"gameinput.togglewield": "Достать/убрать оружие",
|
||||
"gameinput.interact": "Взаимодействовать",
|
||||
"gameinput.freelook": "Свободная камера",
|
||||
|
||||
/// End GameInput section
|
||||
|
||||
|
||||
/// Start chracter selection section
|
||||
"char_selection.delete_permanently": "Навсегда удалить этого персонажа?",
|
||||
"char_selection.change_server": "Сменить сервер",
|
||||
"char_selection.enter_world": "Войти в мир",
|
||||
"char_selection.logout": "Выйти в меню",
|
||||
"char_selection.create_new_charater": "Создать нового персонажа",
|
||||
"char_selection.character_creation": "Создание персонажа",
|
||||
|
||||
"char_selection.human_default": "Стандартный человек",
|
||||
"char_selection.level_fmt": "Уровень {level_nb}",
|
||||
"char_selection.uncanny_valley": "Uncanny Valley",
|
||||
"char_selection.plains_of_uncertainty": "Plains of Uncertainty",
|
||||
"char_selection.beard": "Борода",
|
||||
"char_selection.hair_style": "Прическа",
|
||||
"char_selection.hair_color": "Цвет волос",
|
||||
"char_selection.chest_color": "Цвет нагрудника",
|
||||
"char_selection.eye_color": "Цвет глаз",
|
||||
"char_selection.skin": "Кожа",
|
||||
"char_selection.eyebrows": "Брови",
|
||||
"char_selection.accessories": "Аксессуары",
|
||||
|
||||
/// End chracter selection section
|
||||
|
||||
|
||||
/// Start character window section
|
||||
"character_window.character_name": "Имя персонажа",
|
||||
// Charater stats
|
||||
"character_window.character_stats": r#"Стойкость
|
||||
|
||||
Выносливость
|
||||
|
||||
Сила воли
|
||||
"#,
|
||||
|
||||
|
||||
/// Start character window section
|
||||
|
||||
|
||||
/// Start Escape Menu Section
|
||||
"esc_menu.logout": "Выйти в меню",
|
||||
"esc_menu.quit_game": "Выйти из игры",
|
||||
/// End Escape Menu Section
|
||||
}
|
||||
)
|
@ -263,6 +263,31 @@
|
||||
"voxel.armor.shoulder.plate_right-0",
|
||||
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
|
||||
),
|
||||
//Steel0 Armor
|
||||
Armor(Chest(Steel0)): VoxTrans(
|
||||
"voxel.armor.chest.steel-0",
|
||||
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
|
||||
),
|
||||
Armor(Pants(Steel0)): VoxTrans(
|
||||
"voxel.armor.pants.steel-0",
|
||||
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
|
||||
),
|
||||
Armor(Belt(Steel0)): VoxTrans(
|
||||
"voxel.armor.belt.steel-0",
|
||||
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.8,
|
||||
),
|
||||
Armor(Foot(Steel0)): VoxTrans(
|
||||
"voxel.armor.foot.steel-0",
|
||||
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
|
||||
),
|
||||
Armor(Hand(Steel0)): VoxTrans(
|
||||
"voxel.armor.hand.steel_right-0",
|
||||
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
|
||||
),
|
||||
Armor(Shoulder(Steel0)): VoxTrans(
|
||||
"voxel.armor.shoulder.steel_right-0",
|
||||
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
|
||||
),
|
||||
//Leather0 Armor
|
||||
Armor(Chest(Leather0)): VoxTrans(
|
||||
"voxel.armor.chest.leather-0",
|
||||
@ -284,12 +309,38 @@
|
||||
"voxel.armor.hand.leather_right-0",
|
||||
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
|
||||
),
|
||||
Armor(Shoulder(Leather0)): VoxTrans(
|
||||
"voxel.armor.shoulder.leather_right-0",
|
||||
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
|
||||
),
|
||||
//Leather1 Armor
|
||||
Armor(Shoulder(Leather1)): VoxTrans(
|
||||
"voxel.armor.shoulder.leather_right-1",
|
||||
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
|
||||
),
|
||||
Armor(Shoulder(Leather0)): VoxTrans(
|
||||
"voxel.armor.shoulder.leather_right-0",
|
||||
//Leather2 Armor
|
||||
Armor(Chest(Leather2)): VoxTrans(
|
||||
"voxel.armor.chest.leather-2",
|
||||
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
|
||||
),
|
||||
Armor(Pants(Leather2)): VoxTrans(
|
||||
"voxel.armor.pants.leather-2",
|
||||
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
|
||||
),
|
||||
Armor(Belt(Leather2)): VoxTrans(
|
||||
"voxel.armor.belt.leather-2",
|
||||
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.8,
|
||||
),
|
||||
Armor(Foot(Leather2)): VoxTrans(
|
||||
"voxel.armor.foot.leather-2",
|
||||
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
|
||||
),
|
||||
Armor(Hand(Leather2)): VoxTrans(
|
||||
"voxel.armor.hand.leather_right-2",
|
||||
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
|
||||
),
|
||||
Armor(Shoulder(Leather2)): VoxTrans(
|
||||
"voxel.armor.shoulder.leather_right-2",
|
||||
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
|
||||
),
|
||||
//Linen Cloth
|
||||
|
@ -124,7 +124,7 @@ void main() {
|
||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||
|
||||
if ((flags & 1) == 1 && int(cam_mode) == 1) {
|
||||
float distance = distance(vec3(cam_pos), vec3(model_mat * vec4(vec3(0), 1))) - 2;
|
||||
float distance = distance(vec3(cam_pos), focus_pos.xyz) - 2;
|
||||
|
||||
float opacity = clamp(distance / distance_divider, 0, 1);
|
||||
|
||||
|
@ -57,6 +57,8 @@ void main() {
|
||||
combined_mat *
|
||||
vec4(pos, 1)).xyz;
|
||||
|
||||
f_pos.z -= 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0);
|
||||
|
||||
f_col = srgb_to_linear(vec3((uvec3(v_col) >> uvec3(0, 8, 16)) & uvec3(0xFFu)) / 255.0);
|
||||
|
||||
f_ao = float(v_ao_bone & 0x3u) / 4.0;
|
||||
|
@ -44,7 +44,7 @@ uniform u_bones {
|
||||
out vec4 tgt_color;
|
||||
|
||||
void main() {
|
||||
float distance = distance(vec3(cam_pos), vec3(model_mat * vec4(vec3(0), 1))) - 2;
|
||||
float distance = distance(vec3(cam_pos), focus_pos.xyz) - 2;
|
||||
|
||||
float opacity = clamp(distance / distance_divider, 0, 1);
|
||||
|
||||
|
BIN
assets/voxygen/voxel/armor/belt/leather-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/belt/leather-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/belt/steel-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/belt/steel-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/chest/leather-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/chest/leather-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/chest/steel-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/chest/steel-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/foot/leather-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/foot/leather-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/foot/steel-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/foot/steel-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/hand/leather_left-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/hand/leather_left-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/hand/leather_right-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/hand/leather_right-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/hand/steel_left-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/hand/steel_left-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/hand/steel_right-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/hand/steel_right-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/pants/leather-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/pants/leather-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/pants/steel-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/pants/steel-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/shoulder/leather_left-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/shoulder/leather_left-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/shoulder/leather_right-2.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/shoulder/leather_right-2.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/shoulder/steel_left-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/shoulder/steel_left-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/armor/shoulder/steel_right-0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/armor/shoulder/steel_right-0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -52,5 +52,13 @@
|
||||
vox_spec: ("armor.belt.cultist", (-5.0, -3.5, 1.0)),
|
||||
color: None
|
||||
),
|
||||
Leather2:(
|
||||
vox_spec: ("armor.belt.leather-2", (-5.0, -3.5, 2.0)),
|
||||
color: None
|
||||
),
|
||||
Steel0:(
|
||||
vox_spec: ("armor.belt.steel-0", (-5.0, -4.5, 2.0)),
|
||||
color: None
|
||||
),
|
||||
},
|
||||
))
|
||||
|
@ -110,5 +110,14 @@
|
||||
vox_spec: ("armor.chest.cultist", (-7.0, -3.5, 2.0)),
|
||||
color: Some((57, 81, 132))
|
||||
),
|
||||
Steel0:(
|
||||
vox_spec: ("armor.chest.steel-0", (-8.0, -4.5, 2.0)),
|
||||
color: None
|
||||
),
|
||||
Leather2:(
|
||||
vox_spec: ("armor.chest.leather-2", (-7.0, -3.5, 2.0)),
|
||||
color: None
|
||||
),
|
||||
},
|
||||
))
|
||||
)
|
||||
)
|
@ -44,5 +44,13 @@
|
||||
vox_spec: ("armor.foot.cultist", (-2.5, -3.5, -9.0)),
|
||||
color: None
|
||||
),
|
||||
Steel0:(
|
||||
vox_spec: ("armor.foot.steel-0", (-2.5, -3.5, -9.0)),
|
||||
color: None
|
||||
),
|
||||
Leather2:(
|
||||
vox_spec: ("armor.foot.leather-2", (-2.5, -3.5, -9.0)),
|
||||
color: None
|
||||
),
|
||||
},
|
||||
))
|
||||
|
@ -100,6 +100,25 @@
|
||||
color: Some((57, 81, 132))
|
||||
)
|
||||
),
|
||||
|
||||
Steel0: (
|
||||
left: (
|
||||
vox_spec: ("armor.hand.steel_left-0", (-1.5, -1.5, -7.0)),
|
||||
color: None
|
||||
),
|
||||
right: (
|
||||
vox_spec: ("armor.hand.steel_right-0", (-1.5, -1.5, -7.0)),
|
||||
color: None
|
||||
)
|
||||
),
|
||||
Leather2: (
|
||||
left: (
|
||||
vox_spec: ("armor.hand.leather_left-2", (-1.5, -1.5, -7.0)),
|
||||
color: None
|
||||
),
|
||||
right: (
|
||||
vox_spec: ("armor.hand.leather_right-2", (-1.5, -1.5, -7.0)),
|
||||
color: None
|
||||
)
|
||||
),
|
||||
},
|
||||
))
|
||||
|
@ -68,5 +68,13 @@
|
||||
vox_spec: ("armor.pants.cultist", (-5.0, -3.5, 1.0)),
|
||||
color: Some((57, 81, 132))
|
||||
),
|
||||
Steel0:(
|
||||
vox_spec: ("armor.pants.steel-0", (-6.0, -4.5, 1.0)),
|
||||
color: None
|
||||
),
|
||||
Leather2:(
|
||||
vox_spec: ("armor.pants.leather-2", (-5.0, -3.5, 1.0)),
|
||||
color: None
|
||||
),
|
||||
},
|
||||
))
|
||||
|
@ -131,5 +131,25 @@
|
||||
color: Some((57, 81, 132))
|
||||
)
|
||||
),
|
||||
Steel0: (
|
||||
left: (
|
||||
vox_spec: ("armor.shoulder.steel_left-0", (-5.0, -4.5 , 0.0)),
|
||||
color: None
|
||||
),
|
||||
right: (
|
||||
vox_spec: ("armor.shoulder.steel_right-0", (-1.0, -4.5, 0.0)),
|
||||
color: None
|
||||
)
|
||||
),
|
||||
Leather2: (
|
||||
left: (
|
||||
vox_spec: ("armor.shoulder.leather_left-2", (-5.0, -3.8, -0.9)),
|
||||
color: None
|
||||
),
|
||||
right: (
|
||||
vox_spec: ("armor.shoulder.leather_right-2", (-1.0, -3.8, -0.9)),
|
||||
color: None
|
||||
)
|
||||
),
|
||||
},
|
||||
))
|
||||
|
BIN
assets/voxygen/voxel/sprite/door/door-0.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/sprite/door/door-0.vox
(Stored with Git LFS)
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veloren-chat-cli"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veloren-client"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veloren-common"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>", "Maciej Ćwięka <mckol363@gmail.com>", "Imbris <imbrisf@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
@ -296,7 +296,7 @@ lazy_static! {
|
||||
}
|
||||
|
||||
// System paths
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
||||
{
|
||||
if let Ok(result) = std::env::var("XDG_DATA_HOME") {
|
||||
paths.push(format!("{}/veloren/assets", result).into());
|
||||
|
@ -55,10 +55,9 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
|
||||
pub const ALL_SPECIES: [Species; 2] = [Species::Ogre, Species::Cyclops];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -82,10 +82,9 @@ pub const ALL_SPECIES: [Species; 8] = [
|
||||
];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -72,10 +72,9 @@ pub const ALL_SPECIES: [Species; 6] = [
|
||||
];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -52,10 +52,9 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
|
||||
pub const ALL_SPECIES: [Species; 1] = [Species::Reddragon];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -52,10 +52,9 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
|
||||
pub const ALL_SPECIES: [Species; 1] = [Species::StoneGolem];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -105,10 +105,9 @@ pub const ALL_RACES: [Race; 6] = [
|
||||
];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Race;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_RACES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -82,10 +82,9 @@ pub const ALL_SPECIES: [Species; 8] = [
|
||||
];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,9 @@ pub const ALL_SPECIES: [Species; 13] = [
|
||||
];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
type IntoIter = impl Iterator<Item = Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,17 @@ impl CharacterState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_aimed(&self) -> bool {
|
||||
match self {
|
||||
CharacterState::BasicMelee(_)
|
||||
| CharacterState::BasicRanged(_)
|
||||
| CharacterState::DashMelee(_)
|
||||
| CharacterState::TripleStrike(_)
|
||||
| CharacterState::BasicBlock => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_block(&self) -> bool {
|
||||
match self {
|
||||
CharacterState::BasicBlock => true,
|
||||
|
@ -27,8 +27,10 @@ pub enum Chest {
|
||||
WorkerOrange1 = 24,
|
||||
CultistPurple = 25,
|
||||
CultistBlue = 26,
|
||||
Steel0 = 27,
|
||||
Leather2 = 28,
|
||||
}
|
||||
pub const ALL_CHESTS: [Chest; 26] = [
|
||||
pub const ALL_CHESTS: [Chest; 28] = [
|
||||
Chest::Blue,
|
||||
Chest::Brown,
|
||||
Chest::Dark,
|
||||
@ -55,6 +57,8 @@ pub const ALL_CHESTS: [Chest; 26] = [
|
||||
Chest::WorkerOrange1,
|
||||
Chest::CultistPurple,
|
||||
Chest::CultistBlue,
|
||||
Chest::Steel0,
|
||||
Chest::Leather2,
|
||||
];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -72,8 +76,11 @@ pub enum Belt {
|
||||
ClothBlue0 = 9,
|
||||
ClothGreen0 = 10,
|
||||
Cultist = 11,
|
||||
Leather2 = 12,
|
||||
Steel0 = 13,
|
||||
}
|
||||
pub const ALL_BELTS: [Belt; 12] = [
|
||||
|
||||
pub const ALL_BELTS: [Belt; 14] = [
|
||||
Belt::None,
|
||||
Belt::Dark,
|
||||
Belt::TurqCloth,
|
||||
@ -86,6 +93,8 @@ pub const ALL_BELTS: [Belt; 12] = [
|
||||
Belt::ClothBlue0,
|
||||
Belt::ClothGreen0,
|
||||
Belt::Cultist,
|
||||
Belt::Leather2,
|
||||
Belt::Steel0,
|
||||
];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -108,8 +117,10 @@ pub enum Pants {
|
||||
WorkerBlue0 = 14,
|
||||
CultistPurple = 15,
|
||||
CultistBlue = 16,
|
||||
Steel0 = 17,
|
||||
Leather2 = 18,
|
||||
}
|
||||
pub const ALL_PANTS: [Pants; 17] = [
|
||||
pub const ALL_PANTS: [Pants; 19] = [
|
||||
Pants::None,
|
||||
Pants::Blue,
|
||||
Pants::Brown,
|
||||
@ -127,6 +138,8 @@ pub const ALL_PANTS: [Pants; 17] = [
|
||||
Pants::WorkerBlue0,
|
||||
Pants::CultistPurple,
|
||||
Pants::CultistBlue,
|
||||
Pants::Steel0,
|
||||
Pants::Leather2,
|
||||
];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -141,8 +154,10 @@ pub enum Hand {
|
||||
ClothGreen0 = 7,
|
||||
CultistPurple = 8,
|
||||
CultistBlue = 9,
|
||||
Steel0 = 10,
|
||||
Leather2 = 11,
|
||||
}
|
||||
pub const ALL_HANDS: [Hand; 9] = [
|
||||
pub const ALL_HANDS: [Hand; 11] = [
|
||||
Hand::Cloth,
|
||||
Hand::Assassin,
|
||||
Hand::Plate0,
|
||||
@ -152,6 +167,8 @@ pub const ALL_HANDS: [Hand; 9] = [
|
||||
Hand::ClothGreen0,
|
||||
Hand::CultistPurple,
|
||||
Hand::CultistBlue,
|
||||
Hand::Steel0,
|
||||
Hand::Leather2,
|
||||
];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -167,8 +184,11 @@ pub enum Foot {
|
||||
ClothBlue0 = 8,
|
||||
ClothGreen0 = 9,
|
||||
Cultist = 10,
|
||||
Steel0 = 11,
|
||||
Leather2 = 12,
|
||||
}
|
||||
pub const ALL_FEET: [Foot; 10] = [
|
||||
|
||||
pub const ALL_FEET: [Foot; 12] = [
|
||||
Foot::Dark,
|
||||
Foot::Sandal0,
|
||||
Foot::Jester,
|
||||
@ -179,6 +199,8 @@ pub const ALL_FEET: [Foot; 10] = [
|
||||
Foot::ClothBlue0,
|
||||
Foot::ClothGreen0,
|
||||
Foot::Cultist,
|
||||
Foot::Steel0,
|
||||
Foot::Leather2,
|
||||
];
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -195,8 +217,10 @@ pub enum Shoulder {
|
||||
ClothGreen0 = 9,
|
||||
CultistPurple = 10,
|
||||
CultistBlue = 11,
|
||||
Steel0 = 12,
|
||||
Leather2 = 13,
|
||||
}
|
||||
pub const ALL_SHOULDERS: [Shoulder; 11] = [
|
||||
pub const ALL_SHOULDERS: [Shoulder; 13] = [
|
||||
Shoulder::Brown1,
|
||||
Shoulder::Chain,
|
||||
Shoulder::Assassin,
|
||||
@ -208,6 +232,8 @@ pub const ALL_SHOULDERS: [Shoulder; 11] = [
|
||||
Shoulder::ClothGreen0,
|
||||
Shoulder::CultistPurple,
|
||||
Shoulder::CultistBlue,
|
||||
Shoulder::Steel0,
|
||||
Shoulder::Leather2,
|
||||
];
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
|
@ -123,6 +123,8 @@ impl Item {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_from_asset(asset: &str) -> Self { (*assets::load_expect::<Self>(asset)).clone() }
|
||||
|
||||
pub fn set_amount(&mut self, give_amount: u32) -> Result<(), assets::Error> {
|
||||
use ItemKind::*;
|
||||
match self.kind {
|
||||
@ -235,3 +237,10 @@ impl Item {
|
||||
impl Component for Item {
|
||||
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct ItemDrop(pub Item);
|
||||
|
||||
impl Component for ItemDrop {
|
||||
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ pub mod slot;
|
||||
|
||||
use crate::assets;
|
||||
use item::{Consumable, Item, ItemKind};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use specs::{Component, FlaggedStorage, HashMapStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
use std::ops::Not;
|
||||
@ -305,15 +304,6 @@ impl Default for Inventory {
|
||||
};
|
||||
inventory.push(assets::load_expect_cloned("common.items.cheese"));
|
||||
inventory.push(assets::load_expect_cloned("common.items.apple"));
|
||||
let mut rng = thread_rng();
|
||||
let starter_lantern = [
|
||||
"common.items.lantern.black_0",
|
||||
"common.items.lantern.red_0",
|
||||
"common.items.lantern.blue_0",
|
||||
]
|
||||
.choose(&mut rng)
|
||||
.unwrap();
|
||||
inventory.push(assets::load_expect_cloned(starter_lantern));
|
||||
inventory
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ lazy_static! {
|
||||
}
|
||||
/// The `Default` inventory should contain 3 items: cheese, apple, lantern
|
||||
#[test]
|
||||
fn create_default_count() { assert_eq!(Inventory::default().count(), 3) }
|
||||
fn create_default_count() { assert_eq!(Inventory::default().count(), 2) }
|
||||
|
||||
/// Attempting to push into a full inventory should return the same item.
|
||||
#[test]
|
||||
|
@ -31,7 +31,9 @@ pub use controller::{
|
||||
pub use energy::{Energy, EnergySource};
|
||||
pub use inputs::CanBuild;
|
||||
pub use inventory::{
|
||||
item, item::Item, slot, Inventory, InventoryUpdate, InventoryUpdateEvent, MAX_PICKUP_RANGE_SQR,
|
||||
item,
|
||||
item::{Item, ItemDrop},
|
||||
slot, Inventory, InventoryUpdate, InventoryUpdateEvent, MAX_PICKUP_RANGE_SQR,
|
||||
};
|
||||
pub use last::Last;
|
||||
pub use location::{Waypoint, WaypointArea};
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{comp, sync::Uid, util::Dir};
|
||||
use comp::{item::ToolKind, InventoryUpdateEvent};
|
||||
use comp::{item::ToolKind, InventoryUpdateEvent, Item};
|
||||
use parking_lot::Mutex;
|
||||
use serde::Deserialize;
|
||||
use specs::Entity as EcsEntity;
|
||||
@ -107,6 +107,7 @@ pub enum ServerEvent {
|
||||
agent: comp::Agent,
|
||||
alignment: comp::Alignment,
|
||||
scale: comp::Scale,
|
||||
drop_item: Option<Item>,
|
||||
},
|
||||
CreateWaypoint(Vec3<f32>),
|
||||
ClientDisconnect(EcsEntity),
|
||||
|
@ -16,6 +16,9 @@ pub struct EntityInfo {
|
||||
pub body: Body,
|
||||
pub name: Option<String>,
|
||||
pub main_tool: Option<Item>,
|
||||
pub scale: f32,
|
||||
pub level: Option<u32>,
|
||||
pub loot_drop: Option<Item>,
|
||||
}
|
||||
|
||||
impl EntityInfo {
|
||||
@ -28,6 +31,9 @@ impl EntityInfo {
|
||||
body: Body::Humanoid(humanoid::Body::random()),
|
||||
name: None,
|
||||
main_tool: Some(Item::empty()),
|
||||
scale: 1.0,
|
||||
level: None,
|
||||
loot_drop: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,6 +74,21 @@ impl EntityInfo {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_loot_drop(mut self, loot_drop: Item) -> Self {
|
||||
self.loot_drop = Some(loot_drop);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_scale(mut self, scale: f32) -> Self {
|
||||
self.scale = scale;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_level(mut self, level: u32) -> Self {
|
||||
self.level = Some(level);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_automatic_name(mut self) -> Self {
|
||||
self.name = match &self.body {
|
||||
Body::Humanoid(body) => Some(get_npc_name(&NPC_NAMES.humanoid, body.race)),
|
||||
|
@ -153,6 +153,7 @@ impl State {
|
||||
ecs.register::<comp::Waypoint>();
|
||||
ecs.register::<comp::Projectile>();
|
||||
ecs.register::<comp::Attacking>();
|
||||
ecs.register::<comp::ItemDrop>();
|
||||
|
||||
// Register synced resources used by the ECS.
|
||||
ecs.insert(TimeOfDay(0.0));
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veloren-server-cli"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veloren-server"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{sys, Server, StateExt};
|
||||
use common::{
|
||||
comp::{
|
||||
self, Agent, Alignment, Body, Gravity, LightEmitter, Loadout, Pos, Projectile, Scale,
|
||||
Stats, Vel, WaypointArea,
|
||||
self, Agent, Alignment, Body, Gravity, Item, ItemDrop, LightEmitter, Loadout, Pos,
|
||||
Projectile, Scale, Stats, Vel, WaypointArea,
|
||||
},
|
||||
util::Dir,
|
||||
};
|
||||
@ -32,14 +32,22 @@ pub fn handle_create_npc(
|
||||
agent: Agent,
|
||||
alignment: Alignment,
|
||||
scale: Scale,
|
||||
drop_item: Option<Item>,
|
||||
) {
|
||||
server
|
||||
let entity = server
|
||||
.state
|
||||
.create_npc(pos, stats, loadout, body)
|
||||
.with(agent)
|
||||
.with(scale)
|
||||
.with(alignment)
|
||||
.build();
|
||||
.with(alignment);
|
||||
|
||||
let entity = if let Some(drop_item) = drop_item {
|
||||
entity.with(ItemDrop(drop_item))
|
||||
} else {
|
||||
entity
|
||||
};
|
||||
|
||||
entity.build();
|
||||
}
|
||||
|
||||
pub fn handle_shoot(
|
||||
|
@ -106,10 +106,17 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
.ecs()
|
||||
.write_storage()
|
||||
.insert(entity, Body::Object(object::Body::Pouch));
|
||||
let _ = state.ecs().write_storage().insert(
|
||||
entity,
|
||||
assets::load_expect_cloned::<Item>("common.items.cheese"),
|
||||
);
|
||||
|
||||
let mut item_drops = state.ecs().write_storage::<comp::ItemDrop>();
|
||||
let item = if let Some(item_drop) = item_drops.get(entity).cloned() {
|
||||
item_drops.remove(entity);
|
||||
item_drop.0
|
||||
} else {
|
||||
assets::load_expect_cloned::<Item>("common.items.cheese")
|
||||
};
|
||||
|
||||
let _ = state.ecs().write_storage().insert(entity, item);
|
||||
|
||||
state.ecs().write_storage::<comp::Stats>().remove(entity);
|
||||
state.ecs().write_storage::<comp::Agent>().remove(entity);
|
||||
state
|
||||
|
@ -84,7 +84,10 @@ impl Server {
|
||||
agent,
|
||||
alignment,
|
||||
scale,
|
||||
} => handle_create_npc(self, pos, stats, loadout, body, agent, alignment, scale),
|
||||
drop_item,
|
||||
} => handle_create_npc(
|
||||
self, pos, stats, loadout, body, agent, alignment, scale, drop_item,
|
||||
),
|
||||
ServerEvent::CreateWaypoint(pos) => handle_create_waypoint(self, pos),
|
||||
ServerEvent::ClientDisconnect(entity) => {
|
||||
frontend_events.push(handle_client_disconnect(self, entity))
|
||||
|
@ -42,7 +42,6 @@ pub fn handle_exit_ingame(server: &mut Server, entity: EcsEntity) {
|
||||
}
|
||||
|
||||
pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event {
|
||||
let db_dir = &server.server_settings.persistence_db_dir.clone();
|
||||
let state = server.state_mut();
|
||||
|
||||
// Tell other clients to remove from player list
|
||||
@ -73,12 +72,13 @@ pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event
|
||||
}
|
||||
|
||||
// Sync the player's character data to the database
|
||||
if let (Some(player), Some(stats)) = (
|
||||
if let (Some(player), Some(stats), updater) = (
|
||||
state.read_storage::<Player>().get(entity),
|
||||
state.read_storage::<comp::Stats>().get(entity),
|
||||
state.ecs().read_resource::<persistence::stats::Updater>(),
|
||||
) {
|
||||
if let Some(character_id) = player.character_id {
|
||||
persistence::stats::update_item(character_id, stats, db_dir);
|
||||
updater.update(character_id, stats);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,12 @@ impl Server {
|
||||
.insert(AuthProvider::new(settings.auth_server_address.clone()));
|
||||
state.ecs_mut().insert(Tick(0));
|
||||
state.ecs_mut().insert(ChunkGenerator::new());
|
||||
state.ecs_mut().insert(persistence::stats::Updater::new(
|
||||
settings.persistence_db_dir.clone(),
|
||||
));
|
||||
state.ecs_mut().insert(crate::settings::PersistenceDBDir(
|
||||
settings.persistence_db_dir.clone(),
|
||||
));
|
||||
|
||||
// System timers for performance monitoring
|
||||
state.ecs_mut().insert(sys::EntitySyncTimer::default());
|
||||
@ -117,9 +123,6 @@ impl Server {
|
||||
// Server-only components
|
||||
state.ecs_mut().register::<RegionSubscription>();
|
||||
state.ecs_mut().register::<Client>();
|
||||
state.ecs_mut().insert(crate::settings::PersistenceDBDir(
|
||||
settings.persistence_db_dir.clone(),
|
||||
));
|
||||
|
||||
#[cfg(feature = "worldgen")]
|
||||
let world = World::generate(settings.world_seed, WorldOpts {
|
||||
|
@ -2,12 +2,13 @@ extern crate diesel;
|
||||
|
||||
use super::{establish_connection, models::StatsUpdate, schema};
|
||||
use crate::comp;
|
||||
use crossbeam::channel;
|
||||
use diesel::prelude::*;
|
||||
|
||||
fn update(character_id: i32, stats: &comp::Stats, connection: &SqliteConnection) {
|
||||
fn update(character_id: i32, stats: &StatsUpdate, connection: &SqliteConnection) {
|
||||
if let Err(error) =
|
||||
diesel::update(schema::stats::table.filter(schema::stats::character_id.eq(character_id)))
|
||||
.set(&StatsUpdate::from(stats))
|
||||
.set(stats)
|
||||
.execute(connection)
|
||||
{
|
||||
log::warn!(
|
||||
@ -18,12 +19,58 @@ fn update(character_id: i32, stats: &comp::Stats, connection: &SqliteConnection)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_item(character_id: i32, stats: &comp::Stats, db_dir: &str) {
|
||||
update(character_id, stats, &establish_connection(db_dir));
|
||||
}
|
||||
|
||||
pub fn batch_update<'a>(updates: impl Iterator<Item = (i32, &'a comp::Stats)>, db_dir: &str) {
|
||||
fn batch_update(updates: impl Iterator<Item = (i32, StatsUpdate)>, db_dir: &str) {
|
||||
let connection = establish_connection(db_dir);
|
||||
if let Err(err) = connection.transaction::<_, diesel::result::Error, _>(|| {
|
||||
updates.for_each(|(character_id, stats_update)| {
|
||||
update(character_id, &stats_update, &connection)
|
||||
});
|
||||
|
||||
updates.for_each(|(character_id, stats)| update(character_id, stats, &connection));
|
||||
Ok(())
|
||||
}) {
|
||||
log::error!("Error during stats batch update transaction: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Updater {
|
||||
update_tx: Option<channel::Sender<Vec<(i32, StatsUpdate)>>>,
|
||||
handle: Option<std::thread::JoinHandle<()>>,
|
||||
}
|
||||
impl Updater {
|
||||
pub fn new(db_dir: String) -> Self {
|
||||
let (update_tx, update_rx) = channel::unbounded::<Vec<(i32, StatsUpdate)>>();
|
||||
let handle = std::thread::spawn(move || {
|
||||
while let Ok(updates) = update_rx.recv() {
|
||||
batch_update(updates.into_iter(), &db_dir);
|
||||
}
|
||||
});
|
||||
|
||||
Self {
|
||||
update_tx: Some(update_tx),
|
||||
handle: Some(handle),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn batch_update<'a>(&self, updates: impl Iterator<Item = (i32, &'a comp::Stats)>) {
|
||||
let updates = updates
|
||||
.map(|(id, stats)| (id, StatsUpdate::from(stats)))
|
||||
.collect();
|
||||
|
||||
if let Err(err) = self.update_tx.as_ref().unwrap().send(updates) {
|
||||
log::error!("Could not send stats updates: {:?}", err);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&self, character_id: i32, stats: &comp::Stats) {
|
||||
self.batch_update(std::iter::once((character_id, stats)));
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Updater {
|
||||
fn drop(&mut self) {
|
||||
drop(self.update_tx.take());
|
||||
if let Err(err) = self.handle.take().unwrap().join() {
|
||||
log::error!("Error from joining stats update thread: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +240,9 @@ impl StateExt for State {
|
||||
back: None,
|
||||
ring: None,
|
||||
neck: None,
|
||||
lantern: None,
|
||||
lantern: Some(assets::load_expect_cloned(
|
||||
"common.items.armor.starter.lantern",
|
||||
)),
|
||||
head: None,
|
||||
tabard: None,
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::{
|
||||
persistence::stats,
|
||||
settings::PersistenceDBDir,
|
||||
sys::{SysScheduler, SysTimer},
|
||||
};
|
||||
use common::comp::{Player, Stats};
|
||||
@ -12,25 +11,22 @@ impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
ReadStorage<'a, Player>,
|
||||
ReadStorage<'a, Stats>,
|
||||
ReadExpect<'a, PersistenceDBDir>,
|
||||
ReadExpect<'a, stats::Updater>,
|
||||
Write<'a, SysScheduler<Self>>,
|
||||
Write<'a, SysTimer<Self>>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(players, player_stats, persistence_db_dir, mut scheduler, mut timer): Self::SystemData,
|
||||
(players, player_stats, updater, mut scheduler, mut timer): Self::SystemData,
|
||||
) {
|
||||
if scheduler.should_run() {
|
||||
timer.start();
|
||||
|
||||
stats::batch_update(
|
||||
updater.batch_update(
|
||||
(&players, &player_stats)
|
||||
.join()
|
||||
.filter_map(|(player, stats)| player.character_id.map(|id| (id, stats))),
|
||||
&persistence_db_dir.0,
|
||||
);
|
||||
|
||||
timer.end();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use super::SysTimer;
|
||||
use crate::{chunk_generator::ChunkGenerator, client::Client, Tick};
|
||||
use common::{
|
||||
assets,
|
||||
comp::{self, item, CharacterAbility, ItemConfig, Player, Pos},
|
||||
comp::{self, item, Alignment, CharacterAbility, ItemConfig, Player, Pos},
|
||||
event::{EventBus, ServerEvent},
|
||||
generation::get_npc_name,
|
||||
msg::ServerMsg,
|
||||
@ -245,20 +245,30 @@ impl<'a> System<'a> for Sys {
|
||||
},
|
||||
};
|
||||
|
||||
let mut scale = 1.0;
|
||||
let mut scale = entity.scale;
|
||||
|
||||
// TODO: Remove this and implement scaling or level depending on stuff like
|
||||
// species instead
|
||||
stats.level.set_level(rand::thread_rng().gen_range(1, 9));
|
||||
stats.level.set_level(
|
||||
entity.level.unwrap_or_else(|| {
|
||||
(rand::thread_rng().gen_range(1, 9) as f32 * scale) as u32
|
||||
}),
|
||||
);
|
||||
|
||||
// Replace stuff if it's a boss
|
||||
if entity.is_giant {
|
||||
if rand::random::<f32>() < 0.65 {
|
||||
let body_new = comp::humanoid::Body::random();
|
||||
body = comp::Body::Humanoid(body_new);
|
||||
let adjective = if let Alignment::Enemy = entity.alignment {
|
||||
"Angry"
|
||||
} else {
|
||||
"Gentle"
|
||||
};
|
||||
stats = comp::Stats::new(
|
||||
format!(
|
||||
"Gentle {} Giant",
|
||||
"{} Giant {}",
|
||||
adjective,
|
||||
get_npc_name(&NPC_NAMES.humanoid, body_new.race)
|
||||
),
|
||||
body,
|
||||
@ -336,6 +346,7 @@ impl<'a> System<'a> for Sys {
|
||||
alignment,
|
||||
agent: comp::Agent::default().with_patrol_origin(entity.pos),
|
||||
scale: comp::Scale(scale),
|
||||
drop_item: entity.loot_drop,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "veloren-voxygen"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
authors = ["Joshua Barretto <joshua.s.barretto@gmail.com>", "Imbris <imbrisf@gmail.com>"]
|
||||
edition = "2018"
|
||||
default-run = "veloren-voxygen"
|
||||
|
@ -207,6 +207,11 @@ pub struct DebugInfo {
|
||||
pub num_figures_visible: u32,
|
||||
}
|
||||
|
||||
pub struct HudInfo {
|
||||
pub is_aiming: bool,
|
||||
pub is_first_person: bool,
|
||||
}
|
||||
|
||||
pub enum Event {
|
||||
SendMessage(String),
|
||||
AdjustMousePan(u32),
|
||||
@ -457,6 +462,7 @@ pub struct Hud {
|
||||
slot_manager: slots::SlotManager,
|
||||
hotbar: hotbar::State,
|
||||
events: Vec<Event>,
|
||||
crosshair_opacity: f32,
|
||||
}
|
||||
|
||||
impl Hud {
|
||||
@ -531,6 +537,7 @@ impl Hud {
|
||||
slot_manager,
|
||||
hotbar: hotbar::State::new(),
|
||||
events: Vec::new(),
|
||||
crosshair_opacity: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,6 +553,7 @@ impl Hud {
|
||||
global_state: &GlobalState,
|
||||
debug_info: DebugInfo,
|
||||
dt: Duration,
|
||||
info: HudInfo,
|
||||
) -> Vec<Event> {
|
||||
let mut events = std::mem::replace(&mut self.events, Vec::new());
|
||||
let (ref mut ui_widgets, ref mut tooltip_manager) = self.ui.set_widgets();
|
||||
@ -604,7 +612,14 @@ impl Hud {
|
||||
.set(self.ids.death_bg, ui_widgets);
|
||||
}
|
||||
// Crosshair
|
||||
if !self.show.help && !stats.is_dead {
|
||||
let show_crosshair = (info.is_aiming || info.is_first_person) && !stats.is_dead;
|
||||
self.crosshair_opacity = Lerp::lerp(
|
||||
self.crosshair_opacity,
|
||||
if show_crosshair { 1.0 } else { 0.0 },
|
||||
5.0 * dt.as_secs_f32(),
|
||||
);
|
||||
|
||||
if !self.show.help {
|
||||
Image::new(
|
||||
// TODO: Do we want to match on this every frame?
|
||||
match global_state.settings.gameplay.crosshair_type {
|
||||
@ -619,7 +634,7 @@ impl Hud {
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
global_state.settings.gameplay.crosshair_transp,
|
||||
self.crosshair_opacity * global_state.settings.gameplay.crosshair_transp,
|
||||
)))
|
||||
.set(self.ids.crosshair_outer, ui_widgets);
|
||||
Image::new(self.imgs.crosshair_inner)
|
||||
@ -2338,6 +2353,7 @@ impl Hud {
|
||||
debug_info: DebugInfo,
|
||||
camera: &Camera,
|
||||
dt: Duration,
|
||||
info: HudInfo,
|
||||
) -> Vec<Event> {
|
||||
// conrod eats tabs. Un-eat a tabstop so tab completion can work
|
||||
if self.ui.ui.global_input().events().any(|event| {
|
||||
@ -2363,7 +2379,7 @@ impl Hud {
|
||||
if let Some(maybe_id) = self.to_focus.take() {
|
||||
self.ui.focus_widget(maybe_id);
|
||||
}
|
||||
let events = self.update_layout(client, global_state, debug_info, dt);
|
||||
let events = self.update_layout(client, global_state, debug_info, dt, info);
|
||||
let camera::Dependents {
|
||||
view_mat, proj_mat, ..
|
||||
} = camera.dependents();
|
||||
|
@ -891,18 +891,45 @@ impl CharSelectionUi {
|
||||
to_select = true;
|
||||
}
|
||||
// Create Button
|
||||
if Button::image(self.imgs.button)
|
||||
let create_button = Button::image(self.imgs.button)
|
||||
.bottom_right_with_margins_on(ui_widgets.window, 10.0, 10.0)
|
||||
.w_h(150.0, 40.0)
|
||||
.hover_image(self.imgs.button_hover)
|
||||
.press_image(self.imgs.button_press)
|
||||
.hover_image(if *name != "Character Name" && *name != "" {
|
||||
self.imgs.button_hover
|
||||
} else {
|
||||
self.imgs.button
|
||||
})
|
||||
.press_image(if *name != "Character Name" && *name != "" {
|
||||
self.imgs.button_press
|
||||
} else {
|
||||
self.imgs.button
|
||||
})
|
||||
.label(&self.voxygen_i18n.get("common.create"))
|
||||
.label_font_id(self.fonts.cyri.conrod_id)
|
||||
.label_color(
|
||||
/* if self.mode { TEXT_COLOR } else { */ TEXT_COLOR, /* , } */
|
||||
)
|
||||
.label_color(if *name != "Character Name" && *name != "" {
|
||||
TEXT_COLOR
|
||||
} else {
|
||||
TEXT_COLOR_2
|
||||
})
|
||||
.label_font_size(self.fonts.cyri.scale(20))
|
||||
.label_y(conrod_core::position::Relative::Scalar(3.0))
|
||||
.label_y(conrod_core::position::Relative::Scalar(3.0));
|
||||
|
||||
if *name == "Character Name" || *name == "" {
|
||||
//TODO: We need a server side list of disallowed names and certain naming rules
|
||||
if create_button
|
||||
.with_tooltip(
|
||||
tooltip_manager,
|
||||
&self.voxygen_i18n.get("char_selection.create_info_name"),
|
||||
"",
|
||||
&tooltip_human,
|
||||
)
|
||||
.bottom_offset(55.0)
|
||||
.x_offset(-10.0)
|
||||
.set(self.ids.create_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{}
|
||||
} else {
|
||||
if create_button
|
||||
.set(self.ids.create_button, ui_widgets)
|
||||
.was_clicked()
|
||||
{
|
||||
@ -916,6 +943,7 @@ impl CharSelectionUi {
|
||||
|
||||
to_select = true;
|
||||
}
|
||||
}
|
||||
// Character Name Input
|
||||
Rectangle::fill_with([320.0, 50.0], color::rgba(0.0, 0.0, 0.0, 0.97))
|
||||
.mid_bottom_with_margin_on(ui_widgets.window, 20.0)
|
||||
|
@ -179,6 +179,11 @@ impl MainMenuUi {
|
||||
"voxygen.background.bg_9",
|
||||
"voxygen.background.bg_10",
|
||||
"voxygen.background.bg_11",
|
||||
"voxygen.background.bg_12",
|
||||
"voxygen.background.bg_13",
|
||||
"voxygen.background.bg_14",
|
||||
"voxygen.background.bg_15",
|
||||
"voxygen.background.bg_16",
|
||||
];
|
||||
let mut rng = thread_rng();
|
||||
|
||||
|
@ -169,9 +169,10 @@ impl Camera {
|
||||
pub fn zoom_switch(&mut self, delta: f32) {
|
||||
if delta > 0_f32 || self.mode != CameraMode::FirstPerson {
|
||||
let t = self.tgt_dist + delta;
|
||||
const MIN_THIRD_PERSON: f32 = 2.35;
|
||||
match self.mode {
|
||||
CameraMode::ThirdPerson => {
|
||||
if t < 1_f32 {
|
||||
if t < MIN_THIRD_PERSON {
|
||||
self.set_mode(CameraMode::FirstPerson);
|
||||
} else {
|
||||
self.tgt_dist = t;
|
||||
@ -179,16 +180,16 @@ impl Camera {
|
||||
},
|
||||
CameraMode::FirstPerson => {
|
||||
self.set_mode(CameraMode::ThirdPerson);
|
||||
self.tgt_dist = 1_f32;
|
||||
self.tgt_dist = MIN_THIRD_PERSON;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the distance of the camera from the target
|
||||
pub fn get_distance(&self) -> f32 { self.tgt_dist }
|
||||
/// Get the distance of the camera from the focus
|
||||
pub fn get_distance(&self) -> f32 { self.dist }
|
||||
|
||||
/// Set the distance of the camera from the target (i.e., zoom).
|
||||
/// Set the distance of the camera from the focus (i.e., zoom).
|
||||
pub fn set_distance(&mut self, dist: f32) { self.tgt_dist = dist; }
|
||||
|
||||
pub fn update(&mut self, time: f64, dt: f32, smoothing_enabled: bool) {
|
||||
@ -198,16 +199,33 @@ impl Camera {
|
||||
self.dist = f32::lerp(
|
||||
self.dist,
|
||||
self.tgt_dist,
|
||||
(delta as f32) / self.interp_time(),
|
||||
0.65 * (delta as f32) / self.interp_time(),
|
||||
);
|
||||
}
|
||||
|
||||
if (self.focus - self.tgt_focus).magnitude() > 0.01 {
|
||||
self.focus = Vec3::lerp(
|
||||
if (self.focus - self.tgt_focus).magnitude_squared() > 0.001 {
|
||||
let lerped_focus = Lerp::lerp(
|
||||
self.focus,
|
||||
self.tgt_focus,
|
||||
(delta as f32) / self.interp_time(),
|
||||
(delta as f32) / self.interp_time()
|
||||
* if matches!(self.mode, CameraMode::FirstPerson) {
|
||||
2.0
|
||||
} else {
|
||||
1.0
|
||||
},
|
||||
);
|
||||
|
||||
// Snap when close enough in x/y, but lerp otherwise
|
||||
if (self.focus.xy() - self.tgt_focus.xy()).magnitude_squared() > 2.0f32.powf(2.0) {
|
||||
self.focus.x = lerped_focus.x;
|
||||
self.focus.y = lerped_focus.y;
|
||||
} else {
|
||||
self.focus.x = self.tgt_focus.x;
|
||||
self.focus.y = self.tgt_focus.y;
|
||||
}
|
||||
|
||||
// Always lerp in z
|
||||
self.focus.z = lerped_focus.z;
|
||||
}
|
||||
|
||||
let lerp_angle = |a: f32, b: f32, rate: f32| {
|
||||
@ -281,5 +299,13 @@ impl Camera {
|
||||
}
|
||||
|
||||
/// Get the mode of the camera
|
||||
pub fn get_mode(&self) -> CameraMode { self.mode }
|
||||
pub fn get_mode(&self) -> CameraMode {
|
||||
// Perfom a bit of a trick... don't report first-person until the camera has
|
||||
// lerped close enough to the player.
|
||||
match self.mode {
|
||||
CameraMode::FirstPerson if self.dist < 0.5 => CameraMode::FirstPerson,
|
||||
CameraMode::FirstPerson => CameraMode::ThirdPerson,
|
||||
mode => mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ pub struct SceneData<'a> {
|
||||
pub mouse_smoothing: bool,
|
||||
pub sprite_render_distance: f32,
|
||||
pub figure_lod_render_distance: f32,
|
||||
pub is_aiming: bool,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
@ -220,7 +221,8 @@ impl Scene {
|
||||
let is_running = ecs
|
||||
.read_storage::<comp::Vel>()
|
||||
.get(scene_data.player_entity)
|
||||
.map(|v| v.0.magnitude_squared() > RUNNING_THRESHOLD.powi(2));
|
||||
.map(|v| v.0.magnitude_squared() > RUNNING_THRESHOLD.powi(2))
|
||||
.unwrap_or(false);
|
||||
|
||||
let on_ground = ecs
|
||||
.read_storage::<comp::PhysicsState>()
|
||||
@ -251,18 +253,18 @@ impl Scene {
|
||||
CameraMode::FirstPerson => {
|
||||
if player_rolling {
|
||||
player_scale * 0.8
|
||||
} else if is_running.unwrap_or(false) && on_ground.unwrap_or(false) {
|
||||
player_scale * 1.6 + (scene_data.state.get_time() as f32 * 17.0).sin() * 0.05
|
||||
} else if is_running && on_ground.unwrap_or(false) {
|
||||
player_scale * 1.65 + (scene_data.state.get_time() as f32 * 17.0).sin() * 0.05
|
||||
} else {
|
||||
player_scale * 1.6
|
||||
player_scale * 1.65
|
||||
}
|
||||
},
|
||||
CameraMode::ThirdPerson => 1.2,
|
||||
CameraMode::ThirdPerson if scene_data.is_aiming => player_scale * 2.1,
|
||||
CameraMode::ThirdPerson => player_scale * 1.65,
|
||||
};
|
||||
|
||||
self.camera.set_focus_pos(
|
||||
player_pos + Vec3::unit_z() * (up + dist * 0.15 - tilt.min(0.0) * dist * 0.4),
|
||||
);
|
||||
self.camera
|
||||
.set_focus_pos(player_pos + Vec3::unit_z() * (up - tilt.min(0.0).sin() * dist * 0.6));
|
||||
|
||||
// Tick camera for interpolation.
|
||||
self.camera.update(
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ecs::MyEntity,
|
||||
hud::{DebugInfo, Event as HudEvent, Hud, PressBehavior},
|
||||
hud::{DebugInfo, Event as HudEvent, Hud, HudInfo, PressBehavior},
|
||||
i18n::{i18n_asset_key, VoxygenLocalization},
|
||||
key_state::KeyState,
|
||||
menu::char_selection::CharSelectionState,
|
||||
@ -170,6 +170,25 @@ impl PlayState for SessionState {
|
||||
_ => cam_pos, // Should never happen, but a safe fallback
|
||||
};
|
||||
|
||||
let (is_aiming, aim_dir_offset) = {
|
||||
let client = self.client.borrow();
|
||||
let is_aiming = client
|
||||
.state()
|
||||
.read_storage::<comp::CharacterState>()
|
||||
.get(client.entity())
|
||||
.map(|cs| cs.is_aimed())
|
||||
.unwrap_or(false);
|
||||
|
||||
(
|
||||
is_aiming,
|
||||
if is_aiming {
|
||||
Vec3::unit_z() * 0.025
|
||||
} else {
|
||||
Vec3::zero()
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
let cam_dir: Vec3<f32> = Vec3::from(view_mat.inverted() * -Vec4::unit_z());
|
||||
|
||||
// Check to see whether we're aiming at anything
|
||||
@ -184,22 +203,17 @@ impl PlayState for SessionState {
|
||||
|
||||
let cam_dist = cam_ray.0;
|
||||
|
||||
if let Ok(Some(_)) = cam_ray.1 {
|
||||
// The ray hit something, is it within pickup range?
|
||||
let select_pos = if player_pos.distance_squared(cam_pos + cam_dir * cam_dist)
|
||||
<= MAX_PICKUP_RANGE_SQR
|
||||
match cam_ray.1 {
|
||||
Ok(Some(_))
|
||||
if player_pos.distance_squared(cam_pos + cam_dir * cam_dist)
|
||||
<= MAX_PICKUP_RANGE_SQR =>
|
||||
{
|
||||
Some((cam_pos + cam_dir * cam_dist).map(|e| e.floor() as i32))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(
|
||||
Some((cam_pos + cam_dir * (cam_dist - 0.01)).map(|e| e.floor() as i32)),
|
||||
select_pos,
|
||||
Some((cam_pos + cam_dir * cam_dist).map(|e| e.floor() as i32)),
|
||||
)
|
||||
} else {
|
||||
(None, None)
|
||||
},
|
||||
_ => (None, None),
|
||||
}
|
||||
};
|
||||
|
||||
@ -227,7 +241,7 @@ impl PlayState for SessionState {
|
||||
},
|
||||
Event::InputUpdate(GameInput::Primary, state) => {
|
||||
// Check the existence of CanBuild component. If it's here, use LMB to
|
||||
// place blocks, if not, use it to attack
|
||||
// break blocks, if not, use it to attack
|
||||
let mut client = self.client.borrow_mut();
|
||||
if state
|
||||
&& client
|
||||
@ -236,8 +250,8 @@ impl PlayState for SessionState {
|
||||
.get(client.entity())
|
||||
.is_some()
|
||||
{
|
||||
if let Some(build_pos) = build_pos {
|
||||
client.place_block(build_pos, self.selected_block);
|
||||
if let Some(select_pos) = select_pos {
|
||||
client.remove_block(select_pos);
|
||||
}
|
||||
} else {
|
||||
self.inputs.primary.set_state(state);
|
||||
@ -256,8 +270,8 @@ impl PlayState for SessionState {
|
||||
.get(client.entity())
|
||||
.is_some()
|
||||
{
|
||||
if let Some(select_pos) = select_pos {
|
||||
client.remove_block(select_pos);
|
||||
if let Some(build_pos) = build_pos {
|
||||
client.place_block(build_pos, self.selected_block);
|
||||
}
|
||||
} else {
|
||||
self.inputs.secondary.set_state(state);
|
||||
@ -444,7 +458,7 @@ impl PlayState for SessionState {
|
||||
|
||||
if !free_look {
|
||||
ori = self.scene.camera().get_orientation();
|
||||
self.inputs.look_dir = Dir::from_unnormalized(cam_dir).unwrap();
|
||||
self.inputs.look_dir = Dir::from_unnormalized(cam_dir + aim_dir_offset).unwrap();
|
||||
}
|
||||
// Calculate the movement input vector of the player from the current key
|
||||
// presses and the camera direction.
|
||||
@ -520,6 +534,13 @@ impl PlayState for SessionState {
|
||||
},
|
||||
&self.scene.camera(),
|
||||
clock.get_last_delta(),
|
||||
HudInfo {
|
||||
is_aiming,
|
||||
is_first_person: matches!(
|
||||
self.scene.camera().get_mode(),
|
||||
camera::CameraMode::FirstPerson
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
// Look for changes in the localization files
|
||||
@ -762,6 +783,7 @@ impl PlayState for SessionState {
|
||||
.graphics
|
||||
.figure_lod_render_distance
|
||||
as f32,
|
||||
is_aiming,
|
||||
};
|
||||
|
||||
// Runs if either in a multiplayer server or the singleplayer server is unpaused
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user