Merge branch 'master' of gitlab.com:veloren/veloren into sharp/small-fixes

This commit is contained in:
Joshua Yanovski 2020-08-07 06:47:10 +02:00
commit 77a8c7c267
84 changed files with 832 additions and 626 deletions

View File

@ -78,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated windowing library (winit 0.19 -> 0.22) - Updated windowing library (winit 0.19 -> 0.22)
- Bow M2 is now a charged attack that scales the longer it's held - Bow M2 is now a charged attack that scales the longer it's held
- Fixed window resizing on Mac OS X. - Fixed window resizing on Mac OS X.
- Dehardcoded many item variants
### Removed ### Removed

22
Cargo.lock generated
View File

@ -3159,11 +3159,11 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.3" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [ dependencies = [
"proc-macro-error-attr 1.0.3", "proc-macro-error-attr 1.0.4",
"proc-macro2 1.0.18", "proc-macro2 1.0.18",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.33", "syn 1.0.33",
@ -3185,14 +3185,12 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro-error-attr" name = "proc-macro-error-attr"
version = "1.0.3" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [ dependencies = [
"proc-macro2 1.0.18", "proc-macro2 1.0.18",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.33",
"syn-mid",
"version_check 0.9.2", "version_check 0.9.2",
] ]
@ -4035,9 +4033,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]] [[package]]
name = "structopt" name = "structopt"
version = "0.3.15" version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" checksum = "de5472fb24d7e80ae84a7801b7978f95a19ec32cb1876faea59ab711eb901976"
dependencies = [ dependencies = [
"clap", "clap",
"lazy_static", "lazy_static",
@ -4046,12 +4044,12 @@ dependencies = [
[[package]] [[package]]
name = "structopt-derive" name = "structopt-derive"
version = "0.4.8" version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" checksum = "1e0eb37335aeeebe51be42e2dc07f031163fbabfa6ac67d7ea68b5c2f68d5f99"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error 1.0.3", "proc-macro-error 1.0.4",
"proc-macro2 1.0.18", "proc-macro2 1.0.18",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.33", "syn 1.0.33",

View File

@ -3,7 +3,7 @@ Item(
description: "Used by city guards.", description: "Used by city guards.",
kind: Lantern( kind: Lantern(
( (
kind: Black0, kind: "Black0",
color: (r: 255, g: 190, b: 75), color: (r: 255, g: 190, b: 75),
strength_thousandths: 3000, strength_thousandths: 3000,
flicker_thousandths: 300, flicker_thousandths: 300,

View File

@ -2,7 +2,7 @@ Item(
name: "Flask of Velorite Dusk", name: "Flask of Velorite Dusk",
description: "Increases Exp by 250\n\nTake with plenty of water\n\n<Right-Click to use>", description: "Increases Exp by 250\n\nTake with plenty of water\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: PotionExp, kind: "PotionExp",
effect: Xp(250), effect: Xp(250),
), ),
) )

View File

@ -3,7 +3,7 @@ Item(
description: "Illuminates even the darkest dungeon\nA great monster was slain for this item", description: "Illuminates even the darkest dungeon\nA great monster was slain for this item",
kind: Lantern( kind: Lantern(
( (
kind: Blue0, kind: "Blue0",
color: (r: 220, g: 220, b: 255), color: (r: 220, g: 220, b: 255),
strength_thousandths: 6500, strength_thousandths: 6500,
flicker_thousandths: 300, flicker_thousandths: 300,

View File

@ -2,7 +2,7 @@ Item(
name: "Potent Potion", name: "Potent Potion",
description: "A potent healing potion.\n\nRestores 100 health on use.\n\n<Right-Click to use>", description: "A potent healing potion.\n\nRestores 100 health on use.\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: Potion, kind: "Potion",
effect: Health(( effect: Health((
amount: 1000, amount: 1000,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Potion of Skill", name: "Potion of Skill",
description: "Provides 250 XP to the drinker\n\n<Right-Click to use>", description: "Provides 250 XP to the drinker\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: Potion, kind: "Potion",
effect: Xp(250), effect: Xp(250),
), ),
) )

View File

@ -2,7 +2,7 @@ Item(
name: "Large Potion", name: "Large Potion",
description: "Restores 100 Health\n\n<Right-Click to use>", description: "Restores 100 Health\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: PotionLarge, kind: "PotionLarge",
effect: Health(( effect: Health((
amount: 1000, amount: 1000,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Medium Potion", name: "Medium Potion",
description: "Restores 70 Health\n\n<Right-Click to use>", description: "Restores 70 Health\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: PotionMed, kind: "PotionMed",
effect: Health(( effect: Health((
amount: 700, amount: 700,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Minor Potion", name: "Minor Potion",
description: "Restores 50 Health\n\n<Right-Click to use>", description: "Restores 50 Health\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: PotionMinor, kind: "PotionMinor",
effect: Health(( effect: Health((
amount: 500, amount: 500,
cause: Item, cause: Item,

View File

@ -2,6 +2,6 @@ Item(
name: "Empty Vial", name: "Empty Vial",
description: "Can be filled with fluids.", description: "Can be filled with fluids.",
kind: Ingredient( kind: Ingredient(
kind: EmptyVial, kind: "EmptyVial",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Leather Scraps", name: "Leather Scraps",
description: "Used to craft various items.", description: "Used to craft various items.",
kind: Ingredient( kind: Ingredient(
kind: LeatherScraps, kind: "LeatherScraps",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Shiny Gem", name: "Shiny Gem",
description: "It's so shiny!", description: "It's so shiny!",
kind: Ingredient( kind: Ingredient(
kind: ShinyGem, kind: "ShinyGem",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Stones", name: "Stones",
description: "Pebbles from the ground.", description: "Pebbles from the ground.",
kind: Ingredient( kind: Ingredient(
kind: Stones, kind: "Stones",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Twigs", name: "Twigs",
description: "Dry.", description: "Dry.",
kind: Ingredient( kind: Ingredient(
kind: Twigs, kind: "Twigs",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Craftsman Hammer", name: "Craftsman Hammer",
description: "Used to craft various items.", description: "Used to craft various items.",
kind: Ingredient( kind: Ingredient(
kind: CraftsmanHammer, kind: "CraftsmanHammer",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Mortar and Pestle", name: "Mortar and Pestle",
description: "Crushes and grinds things into\na fine powder or paste.\nUsed to craft various items.", description: "Crushes and grinds things into\na fine powder or paste.\nUsed to craft various items.",
kind: Ingredient( kind: Ingredient(
kind: MortarPestle, kind: "MortarPestle",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Blue Flower", name: "Blue Flower",
description: "Matches the color of the sky.", description: "Matches the color of the sky.",
kind: Ingredient( kind: Ingredient(
kind: Flower, kind: "Flower",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Pink Flower", name: "Pink Flower",
description: "Looks like a lollipop.", description: "Looks like a lollipop.",
kind: Ingredient( kind: Ingredient(
kind: Flower, kind: "Flower",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Red Flower", name: "Red Flower",
description: "Roses are red...", description: "Roses are red...",
kind: Ingredient( kind: Ingredient(
kind: Flower, kind: "Flower",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Sunflower", name: "Sunflower",
description: "Smells like summer.", description: "Smells like summer.",
kind: Ingredient( kind: Ingredient(
kind: Flower, kind: "Flower",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "White flower", name: "White flower",
description: "Pure and precious.", description: "Pure and precious.",
kind: Ingredient( kind: Ingredient(
kind: Flower, kind: "Flower",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Yellow Flower", name: "Yellow Flower",
description: "Glows like the sun.", description: "Glows like the sun.",
kind: Ingredient( kind: Ingredient(
kind: Flower, kind: "Flower",
) )
) )

View File

@ -2,7 +2,7 @@ Item(
name: "Apple", name: "Apple",
description: "Restores 20 Health\n\nRed and juicy\n\n<Right-Click to use>", description: "Restores 20 Health\n\nRed and juicy\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: Apple, kind: "Apple",
effect: Health(( effect: Health((
amount: 200, amount: 200,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Mushroom Curry", name: "Mushroom Curry",
description: "Restores 120 Health\n\nWho could say no to that?\n\n<Right-Click to use>", description: "Restores 120 Health\n\nWho could say no to that?\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: AppleShroomCurry, kind: "AppleShroomCurry",
effect: Health(( effect: Health((
amount: 1200, amount: 1200,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Apple Stick", name: "Apple Stick",
description: "Restores 60 Health\n\n<Right-Click to use>", description: "Restores 60 Health\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: AppleStick, kind: "AppleStick",
effect: Health(( effect: Health((
amount: 600, amount: 600,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Dwarven Cheese", name: "Dwarven Cheese",
description: "Restores 15 Health\n\nAromatic and nutritious\n\n<Right-Click to use>", description: "Restores 15 Health\n\nAromatic and nutritious\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: Cheese, kind: "Cheese",
effect: Health(( effect: Health((
amount: 150, amount: 150,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Coconut", name: "Coconut",
description: "Restores 30 health\n\nReliable source of water and fat\n\n<Right-Click to use>", description: "Restores 30 health\n\nReliable source of water and fat\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: Coconut, kind: "Coconut",
effect: Health(( effect: Health((
amount: 300, amount: 300,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Mushroom", name: "Mushroom",
description: "Restores 10 Health\n\nHopefully this one is not poisonous\n\n<Right-Click to use>", description: "Restores 10 Health\n\nHopefully this one is not poisonous\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: Mushroom, kind: "Mushroom",
effect: Health(( effect: Health((
amount: 100, amount: 100,
cause: Item, cause: Item,

View File

@ -2,7 +2,7 @@ Item(
name: "Mushroom Stick", name: "Mushroom Stick",
description: "Restores 50 Health\n\n<Right-Click to use>", description: "Restores 50 Health\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: MushroomStick, kind: "MushroomStick",
effect: Health(( effect: Health((
amount: 500, amount: 500,
cause: Item, cause: Item,

View File

@ -2,6 +2,6 @@ Item(
name: "Long Grass", name: "Long Grass",
description: "Greener than an orc's snout.", description: "Greener than an orc's snout.",
kind: Ingredient( kind: Ingredient(
kind: Grass, kind: "Grass",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Medium Grass", name: "Medium Grass",
description: "Greener than an orc's snout.", description: "Greener than an orc's snout.",
kind: Ingredient( kind: Ingredient(
kind: Grass, kind: "Grass",
) )
) )

View File

@ -2,6 +2,6 @@ Item(
name: "Short Grass", name: "Short Grass",
description: "Greener than an orc's snout.", description: "Greener than an orc's snout.",
kind: Ingredient( kind: Ingredient(
kind: Grass, kind: "Grass",
) )
) )

View File

@ -3,7 +3,7 @@ Item(
description: "Used by city guards.", description: "Used by city guards.",
kind: Lantern( kind: Lantern(
( (
kind: Black0, kind: "Black0",
color: (r: 255, g: 190, b: 75), color: (r: 255, g: 190, b: 75),
strength_thousandths: 3000, strength_thousandths: 3000,
flicker_thousandths: 300, flicker_thousandths: 300,

View File

@ -3,7 +3,7 @@ Item(
description: "This lantern is surprisingly cold when lit.", description: "This lantern is surprisingly cold when lit.",
kind: Lantern( kind: Lantern(
( (
kind: Blue0, kind: "Blue0",
color: (r: 64, g: 127, b: 153), color: (r: 64, g: 127, b: 153),
strength_thousandths: 4000, strength_thousandths: 4000,
flicker_thousandths: 250, flicker_thousandths: 250,

View File

@ -3,7 +3,7 @@ Item(
description: "It has an opening that could fit a ring...", description: "It has an opening that could fit a ring...",
kind: Lantern( kind: Lantern(
( (
kind: Green0, kind: "Green0",
color: (r: 192, g: 255, b: 76), color: (r: 192, g: 255, b: 76),
strength_thousandths: 4000, strength_thousandths: 4000,
flicker_thousandths: 500, flicker_thousandths: 500,

View File

@ -3,7 +3,7 @@ Item(
description: "Caution: contents hot", description: "Caution: contents hot",
kind: Lantern( kind: Lantern(
( (
kind: Red0, kind: "Red0",
color: (r: 255, g: 127, b: 51), color: (r: 255, g: 127, b: 51),
strength_thousandths: 3500, strength_thousandths: 3500,
flicker_thousandths: 1000, flicker_thousandths: 1000,

View File

@ -2,7 +2,7 @@ Item(
name: "Velorite", name: "Velorite",
description: "Increases Exp by 20\n\nJust a slight touch makes you feel the knowledge of ancient times\n\n<Right-Click to use>", description: "Increases Exp by 20\n\nJust a slight touch makes you feel the knowledge of ancient times\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: Velorite, kind: "Velorite",
effect: Xp(20), effect: Xp(20),
), ),
) )

View File

@ -2,7 +2,7 @@ Item(
name: "Velorite Fragment", name: "Velorite Fragment",
description: "Increases Exp by 10\n\nSmall runes sparkle on its surface\n\n<Right-Click to use>", description: "Increases Exp by 10\n\nSmall runes sparkle on its surface\n\n<Right-Click to use>",
kind: Consumable( kind: Consumable(
kind: VeloriteFrag, kind: "VeloriteFrag",
effect: Xp(10), effect: Xp(10),
), ),
) )

View File

@ -529,6 +529,10 @@
"troll": { "troll": {
"keyword": "troll", "keyword": "troll",
"generic": "Troll" "generic": "Troll"
},
"dullahan": {
"keyword": "dullahan",
"generic": "Dullahan"
} }
} }
}, },

View File

@ -77,31 +77,31 @@
], ],
threshold: 0.3, threshold: 0.3,
), ),
Inventory(Consumed(Potion)): ( Inventory(Consumed("Potion")): (
files: [ files: [
"voxygen.audio.sfx.inventory.consumable.liquid", "voxygen.audio.sfx.inventory.consumable.liquid",
], ],
threshold: 0.3, threshold: 0.3,
), ),
Inventory(Consumed(PotionMinor)): ( Inventory(Consumed("PotionMinor")): (
files: [ files: [
"voxygen.audio.sfx.inventory.consumable.liquid", "voxygen.audio.sfx.inventory.consumable.liquid",
], ],
threshold: 0.3, threshold: 0.3,
), ),
Inventory(Consumed(Apple)): ( Inventory(Consumed("Apple")): (
files: [ files: [
"voxygen.audio.sfx.inventory.consumable.apple", "voxygen.audio.sfx.inventory.consumable.apple",
], ],
threshold: 0.3, threshold: 0.3,
), ),
Inventory(Consumed(Mushroom)): ( Inventory(Consumed("Mushroom")): (
files: [ files: [
"voxygen.audio.sfx.inventory.consumable.food", "voxygen.audio.sfx.inventory.consumable.food",
], ],
threshold: 0.3, threshold: 0.3,
), ),
Inventory(Consumed(Cheese)): ( Inventory(Consumed("Cheese")): (
files: [ files: [
"voxygen.audio.sfx.inventory.consumable.food", "voxygen.audio.sfx.inventory.consumable.food",
], ],

View File

@ -1,6 +1,6 @@
/// Translation document instructions /// Translation document instructions
/// ///
/// In order to keep localization documents readable please follow the following /// In order to keep localization documents readible please follow the following
/// rules: /// rules:
/// - separate the string map sections using a commentary describing the purpose /// - separate the string map sections using a commentary describing the purpose
/// of the next section /// of the next section
@ -12,14 +12,14 @@
/// ///
/// WARNING: Localization files shall be saved in UTF-8 format without BOM /// WARNING: Localization files shall be saved in UTF-8 format without BOM
/// Localization for "global" Español Latino /// Localization for "latinoamericano" Latin-American
VoxygenLocalization( VoxygenLocalization(
metadata: ( metadata: (
language_name: "Español Latino", language_name: "Español Latino",
language_identifier: "es_la", language_identifier: "es_la",
), ),
convert_utf8_to_ascii: false, convert_utf8_to_ascii: false,
fonts: { fonts: {
"opensans": Font ( "opensans": Font (
asset_key: "voxygen.font.OpenSans-Regular", asset_key: "voxygen.font.OpenSans-Regular",
scale_ratio: 1.0, scale_ratio: 1.0,
@ -44,13 +44,13 @@ VoxygenLocalization(
string_map: { string_map: {
/// Start Common section /// Start Common section
// Texts used in multiple locations with the same formatting // Texts used in multiple locations with the same formatting
"common.username": "usuario", "common.username": "Usuario",
"common.singleplayer": "Un Jugador", "common.singleplayer": "Un Jugador",
"common.multiplayer": "Multijugador", "common.multiplayer": "Multijugador",
"common.servers": "Servidores", "common.servers": "Servidores",
"common.quit": "Salir", "common.quit": "Salir",
"common.settings": "Configuracion", "common.settings": "Configuración",
"common.languages": "Lenguajes", "common.languages": "Idiomas",
"common.interface": "Interfaz", "common.interface": "Interfaz",
"common.gameplay": "Jugabilidad", "common.gameplay": "Jugabilidad",
"common.controls": "Controles", "common.controls": "Controles",
@ -72,17 +72,17 @@ VoxygenLocalization(
"common.fatal_error": "Error Fatal", "common.fatal_error": "Error Fatal",
// Message when connection to the server is lost // Message when connection to the server is lost
"common.connection_lost": r#"Conexion perdida! "common.connection_lost": r#"Conexión perdida!
Se reinicio el servidor? Se reinició el servidor?
El cliente esta actualizado?"#, El cliente está actualizado?"#,
"common.races.orc": "Orco", "common.species.orc": "Orco",
"common.races.human": "Humano", "common.species.human": "Humano",
"common.races.dwarf": "Enano", "common.species.dwarf": "Enano",
"common.races.elf": "Elfo", "common.species.elf": "Elfo",
"common.races.undead": "No-Muerto", "common.species.undead": "No-Muerto",
"common.races.danari": "Danari", "common.species.danari": "Danari",
"common.weapons.axe": "Hacha", "common.weapons.axe": "Hacha",
"common.weapons.sword": "Espada", "common.weapons.sword": "Espada",
@ -95,6 +95,7 @@ El cliente esta actualizado?"#,
/// Start Main screen section /// Start Main screen section
"main.connecting": "Conectando", "main.connecting": "Conectando",
"main.creating_world": "Creando Mundo", "main.creating_world": "Creando Mundo",
"main.tip": "Consejo:",
// Welcome notice that appears the first time Veloren is started // Welcome notice that appears the first time Veloren is started
"main.notice": r#"Bienvenido a la version alfa de Veloren! "main.notice": r#"Bienvenido a la version alfa de Veloren!
@ -105,8 +106,8 @@ Antes de que te diviertas, por favor ten en cuenta lo siguiente:
- Si tienes críticas constructivas o reportes de fallos, puedes contactarnos por reddit, GitLab, o por el server de Discord de nuestra comunidad. - Si tienes críticas constructivas o reportes de fallos, puedes contactarnos por reddit, GitLab, o por el server de Discord de nuestra comunidad.
- Veloren esta licenciado bajo la licencia GPL 3 open-source (código abierto). - Veloren esta licenciado bajo la licencia GPL 3 open-source (código abierto). Eso significa que tienes la libertad de jugar, modificar, y redistribuir el Juego como
Eso significa que tienes la libertad de jugar, modificar, y redistribuir el juego como desees (siempre y cuando dicho trabajo también este licenciado como GPL 3). desees (siempre y cuando dicho trabajo también este licenciado como GPL 3).
- Veloren es un proyecto en comunidad sin ánimo de lucro, y todos los que trabajan en el son voluntarios. - Veloren es un proyecto en comunidad sin ánimo de lucro, y todos los que trabajan en el son voluntarios.
Si te gusta lo que ves, eres bienvenido a unirte a los equipos de desarrollo o de arte! Si te gusta lo que ves, eres bienvenido a unirte a los equipos de desarrollo o de arte!
@ -115,18 +116,16 @@ Gracias por tomarte el tiempo de leer este mensaje, esperamos que disfrutes el j
~ Los Desarrolladores de Veloren"#, ~ Los Desarrolladores de Veloren"#,
/// Login process description // Login process description
"main.login_process": r#"Información sobre el proceso para Iniciar Sesión: "main.login_process": r#"Información sobre el proceso para Iniciar Sesión:
Si estas teniendo problemas iniciando sesión:
Por favor ten en cuenta que ahora necesitas una cuenta Por favor ten en cuenta que ahora necesitas una cuenta
para jugar en servidores con autenticación activada. para jugar en servidores con autenticación activada.
Puedes crearte una cuenta en Puedes crearte una cuenta en
https://account.veloren.net."#, https://account.veloren.net."#,
"main.login.server_not_found": "No se encontró el servidor", "main.login.server_not_found": "No se encontró el servidor",
"main.login.authentication_error": "Error de autenticación en el servidor", "main.login.authentication_error": "Error de autenticación en el servidor",
"main.login.server_full": "El servidor esta lleno", "main.login.server_full": "El servidor esta lleno",
"main.login.untrusted_auth_server": "El servidor de autenticación no es confiable", "main.login.untrusted_auth_server": "El servidor de autenticación no es confiable",
@ -138,7 +137,7 @@ https://account.veloren.net."#,
"main.login.failed_sending_request": "El pedido al servidor de autenticacion fallo", "main.login.failed_sending_request": "El pedido al servidor de autenticacion fallo",
"main.login.invalid_character": "El personaje seleccionado no es válido", "main.login.invalid_character": "El personaje seleccionado no es válido",
"main.login.client_crashed": "El cliente crasheó", "main.login.client_crashed": "El cliente crasheó",
"main.login.not_on_whitelist": "No estas en la lista blanca. Contacta al Dueño del Servidor si quieres unirte.", "main.login.not_on_whitelist": "No estas en la lista blanca. Contacta al Dueño del Servidor si quieres unirte.",
/// End Main screen section /// End Main screen section
@ -148,7 +147,7 @@ https://account.veloren.net."#,
"hud.show_tips": "Mostrar Consejos", "hud.show_tips": "Mostrar Consejos",
"hud.quests": "Misiones", "hud.quests": "Misiones",
"hud.you_died": "Moriste", "hud.you_died": "Moriste",
"hud.waypoint_saved": "Marcador Guardado", "hud.waypoint_saved": "Marcador Guardado",
"hud.press_key_to_show_keybindings_fmt": "Presiona {key} para mostrar los controles del teclado", "hud.press_key_to_show_keybindings_fmt": "Presiona {key} para mostrar los controles del teclado",
"hud.press_key_to_show_debug_info_fmt": "Presiona {key} para mostrar información de depuración", "hud.press_key_to_show_debug_info_fmt": "Presiona {key} para mostrar información de depuración",
@ -167,11 +166,11 @@ https://account.veloren.net."#,
"hud.sct.experience": "{amount} Exp", "hud.sct.experience": "{amount} Exp",
"hud.sct.block": "BLOQUEADO", "hud.sct.block": "BLOQUEADO",
/// Respawn message // Respawn message
"hud.press_key_to_respawn": r#"Presiona {key} para reaparecer en la ultima fogata que visitaste."#, "hud.press_key_to_respawn": r#"Presiona {key} para reaparecer en la ultima fogata que visitaste."#,
/// Welcome message // Welcome message
"hud.welcome": r#"Bienvenido a la alfa de Veloren!, "hud.welcome": r#"Bienvenido a la alfa de Veloren!
Algunos consejos antes de que empieces: Algunos consejos antes de que empieces:
@ -205,7 +204,7 @@ Disfruta tu estadía en el Mundo de Veloren."#,
"hud.temp_quest_headline": r#"Porfavor, ayudanos Viajero!"#, "hud.temp_quest_headline": r#"Porfavor, ayudanos Viajero!"#,
"hud.temp_quest_text": r#"Calabozos llenos de cultistas malvados "hud.temp_quest_text": r#"Calabozos llenos de cultistas malvados
han emergido alrededor de nuestros pacíficos pueblos! han emergido alrededor de nuestros pacíficos pueblos!
Consigue alguien que te acompañe, re-abastecete con comida Consigue alguien que te acompañe, re-abastecete con comida
@ -217,7 +216,7 @@ objetos infundidos con magia?"#,
// Inventory // Inventory
"hud.bag.inventory": "Inventario de {playername}", "hud.bag.inventory": "Inventario de {playername}",
"hud.bag.stats_title": "Estadísticas de {playername}", "hud.bag.stats_title": "Estadísticas de {playername}",
"hud.bag.exp": "Exp", "hud.bag.exp": "Exp",
@ -229,8 +228,8 @@ objetos infundidos con magia?"#,
"hud.bag.shoulders": "Hombros", "hud.bag.shoulders": "Hombros",
"hud.bag.chest": "Torso", "hud.bag.chest": "Torso",
"hud.bag.hands": "Manos", "hud.bag.hands": "Manos",
"hud.bag.lantern": "Farol", "hud.bag.lantern": "Linterna",
"hud.bag.belt": "Cinturon", "hud.bag.belt": "Cinturón",
"hud.bag.ring": "Anillo", "hud.bag.ring": "Anillo",
"hud.bag.back": "Espalda", "hud.bag.back": "Espalda",
"hud.bag.legs": "Piernas", "hud.bag.legs": "Piernas",
@ -243,10 +242,10 @@ objetos infundidos con magia?"#,
"hud.map.map_title": "Mapa", "hud.map.map_title": "Mapa",
"hud.map.qlog_title": "Misiones", "hud.map.qlog_title": "Misiones",
// Settings // Settings
"hud.settings.general": "General", "hud.settings.general": "General",
"hud.settings.none": "Ninguno", "hud.settings.none": "Ninguno",
"hud.settings.press_behavior.toggle": "Alternar", "hud.settings.press_behavior.toggle": "Alternar",
"hud.settings.press_behavior.hold": "Mantener", "hud.settings.press_behavior.hold": "Mantener",
"hud.settings.help_window": "Ventana de Ayuda", "hud.settings.help_window": "Ventana de Ayuda",
"hud.settings.debug_info": "Info de Depuración", "hud.settings.debug_info": "Info de Depuración",
@ -257,7 +256,7 @@ objetos infundidos con magia?"#,
"hud.settings.crosshair": "Mira", "hud.settings.crosshair": "Mira",
"hud.settings.transparency": "Transparencia", "hud.settings.transparency": "Transparencia",
"hud.settings.hotbar": "Inventario Rápido", "hud.settings.hotbar": "Inventario Rápido",
"hud.settings.toggle_shortcuts": "Alternar Atajos", "hud.settings.toggle_shortcuts": "Alternar Atajos",
"hud.settings.toggle_bar_experience": "Alternar Barra de Experiencia", "hud.settings.toggle_bar_experience": "Alternar Barra de Experiencia",
"hud.settings.scrolling_combat_text": "Texto de Combate con Desplazamiento", "hud.settings.scrolling_combat_text": "Texto de Combate con Desplazamiento",
"hud.settings.single_damage_number": "Números de Daño Singular", "hud.settings.single_damage_number": "Números de Daño Singular",
@ -266,13 +265,14 @@ objetos infundidos con magia?"#,
"hud.settings.cumulated_incoming_damage": "Daño Recibido Acumulado", "hud.settings.cumulated_incoming_damage": "Daño Recibido Acumulado",
"hud.settings.speech_bubble": "Burbuja de Diálogo", "hud.settings.speech_bubble": "Burbuja de Diálogo",
"hud.settings.speech_bubble_dark_mode": "Burbuja de Diálogo en Modo Oscuro", "hud.settings.speech_bubble_dark_mode": "Burbuja de Diálogo en Modo Oscuro",
"hud.settings.speech_bubble_icon": "Icono de Burbuja de Diálogo", "hud.settings.speech_bubble_icon": "Burbuja de Diálogo en Modo Oscuro",
"hud.settings.energybar_numbers": "Números de la Barra de Energia", "hud.settings.energybar_numbers": "Números de la Barra de Energia",
"hud.settings.values": "Valores", "hud.settings.values": "Valores",
"hud.settings.percentages": "Porcentajes", "hud.settings.percentages": "Porcentajes",
"hud.settings.chat": "Chat", "hud.settings.chat": "Chat",
"hud.settings.background_transparency": "Transparencia del Fondo", "hud.settings.background_transparency": "Transparencia del Fondo",
"hud.settings.chat_character_name": "Nombres de Personajes en el chat", "hud.settings.chat_character_name": "Nombres de Personajes en el chat",
"hud.settings.loading_tips": "Consejos en Pantalla de Carga",
"hud.settings.pan_sensitivity": "Sensibilidad de Desplazamiento de la Cámara", "hud.settings.pan_sensitivity": "Sensibilidad de Desplazamiento de la Cámara",
"hud.settings.zoom_sensitivity": "Sensibilidad del Zoom", "hud.settings.zoom_sensitivity": "Sensibilidad del Zoom",
@ -280,7 +280,7 @@ objetos infundidos con magia?"#,
"hud.settings.invert_mouse_y_axis": "Invertir eje Y del Ratón", "hud.settings.invert_mouse_y_axis": "Invertir eje Y del Ratón",
"hud.settings.enable_mouse_smoothing": "Suavizado de la Cámara", "hud.settings.enable_mouse_smoothing": "Suavizado de la Cámara",
"hud.settings.free_look_behavior": "Comportamiento de vista libre", "hud.settings.free_look_behavior": "Comportamiento de vista libre",
"hud.settings.auto_walk_behavior": "Comportamiento al caminar automaticamente", "hud.settings.auto_walk_behavior": "Comportamiento al caminar automaticamente",
"hud.settings.stop_auto_walk_on_input": "Frenar caminata automática", "hud.settings.stop_auto_walk_on_input": "Frenar caminata automática",
"hud.settings.view_distance": "Distancia de Visión", "hud.settings.view_distance": "Distancia de Visión",
@ -288,7 +288,7 @@ objetos infundidos con magia?"#,
"hud.settings.figures_view_distance": "Distancia de Visión de Entidades", "hud.settings.figures_view_distance": "Distancia de Visión de Entidades",
"hud.settings.maximum_fps": "FPS Máximos", "hud.settings.maximum_fps": "FPS Máximos",
"hud.settings.fov": "Campo de Visión (grados)", "hud.settings.fov": "Campo de Visión (grados)",
"hud.settings.gamma": "Gama", "hud.settings.gamma": "Gama",
"hud.settings.antialiasing_mode": "Modo Anti-Aliasing", "hud.settings.antialiasing_mode": "Modo Anti-Aliasing",
"hud.settings.cloud_rendering_mode": "Modo de Renderizado de Nubes", "hud.settings.cloud_rendering_mode": "Modo de Renderizado de Nubes",
"hud.settings.fluid_rendering_mode": "Modo de Renderizado de Fluidos", "hud.settings.fluid_rendering_mode": "Modo de Renderizado de Fluidos",
@ -302,21 +302,27 @@ objetos infundidos con magia?"#,
"hud.settings.sound_effect_volume": "Volumen de Efectos de Sonido", "hud.settings.sound_effect_volume": "Volumen de Efectos de Sonido",
"hud.settings.audio_device": "Dispositivo de Audio", "hud.settings.audio_device": "Dispositivo de Audio",
"hud.settings.awaitingkey": "Presiona una tecla...", "hud.settings.awaitingkey": "Presiona una tecla...",
"hud.settings.unbound": "Ninguno", "hud.settings.unbound": "Ninguno",
"hud.settings.reset_keybinds": "Reestablecer a los valores predeterminados", "hud.settings.reset_keybinds": "Reestablecer a los valores predeterminados",
"hud.social": "Social", "hud.social": "Social",
"hud.social.online": "En Linea", "hud.social.online": "En Línea",
"hud.social.friends": "Amigos", "hud.social.friends": "Amigos",
"hud.social.not_yet_available": "Aún no esta disponible", "hud.social.not_yet_available": "Aún no esta disponible",
"hud.social.faction": "Facción", "hud.social.faction": "Facción",
"hud.social.play_online_fmt": "{nb_player} jugador(es) en linea", "hud.social.play_online_fmt": "{nb_player} jugador(es) en línea",
"hud.crafting": "Crafteo",
"hud.crafting.recipes": "Recetas",
"hud.crafting.ingredients": "Ingredientes:",
"hud.crafting.craft": "Fabricar",
"hud.crafting.tool_cata": "Requisitos:",
"hud.spell": "Hechizos", "hud.spell": "Hechizos",
"hud.free_look_indicator": "Vista libre activa", "hud.free_look_indicator": "Vista libre activa",
"hud.auto_walk_indicator": "Caminata automática activa", "hud.auto_walk_indicator": "Caminata automática activa",
/// End HUD section /// End HUD section
@ -357,19 +363,19 @@ objetos infundidos con magia?"#,
"gameinput.mount": "Montar", "gameinput.mount": "Montar",
"gameinput.enter": "Entrar", "gameinput.enter": "Entrar",
"gameinput.command": "Comando", "gameinput.command": "Comando",
"gameinput.escape": "Escape", "gameinput.escape": "Escapar",
"gameinput.map": "Mapa", "gameinput.map": "Mapa",
"gameinput.bag": "Bolsa", "gameinput.bag": "Bolsa",
"gameinput.social": "Social", "gameinput.social": "Social",
"gameinput.sit": "Sentarse", "gameinput.sit": "Sentarse",
"gameinput.spellbook": "Hechizos", "gameinput.spellbook": "Hechizos",
"gameinput.settings": "Configuración", "gameinput.settings": "Configuración",
"gameinput.respawn": "Re-aparecer", "gameinput.respawn": "Reaparecer",
"gameinput.charge": "Cargar", "gameinput.charge": "Cargar",
"gameinput.togglewield": "Alternar empuñadura", "gameinput.togglewield": "Alternar empuñadura",
"gameinput.interact": "Interactuar", "gameinput.interact": "Interactuar",
"gameinput.freelook": "Vista Libre", "gameinput.freelook": "Vista Libre",
"gameinput.autowalk": "Caminata Automática", "gameinput.autowalk": "Caminata Automática",
"gameinput.dance": "Bailar", "gameinput.dance": "Bailar",
/// End GameInput section /// End GameInput section
@ -393,23 +399,25 @@ objetos infundidos con magia?"#,
"char_selection.beard": "Barba", "char_selection.beard": "Barba",
"char_selection.hair_style": "Estilo de Pelo", "char_selection.hair_style": "Estilo de Pelo",
"char_selection.hair_color": "Color de Pelo", "char_selection.hair_color": "Color de Pelo",
"char_selection.chest_color": "Color del Torso",
"char_selection.eye_color": "Color de Ojos", "char_selection.eye_color": "Color de Ojos",
"char_selection.skin": "Piel", "char_selection.skin": "Piel",
"char_selection.eyebrows": "Cejas", "char_selection.eyeshape": "Detalles de los Ojos",
"char_selection.accessories": "Accesorios", "char_selection.accessories": "Accesorios",
"char_selection.create_info_name": "Tu Personaje necesita un nombre!",
/// End chracter selection section /// End chracter selection section
/// Start character window section /// Start character window section
"character_window.character_name": "Nombre de Personaje", "character_window.character_name": "Nombre de Personaje",
// Charater stats // Character stats
"character_window.character_stats": r#"Resistencia "character_window.character_stats": r#"Resistencia
Estado Físico Estado Físico
Fuerza de Voluntad Fuerza de Voluntad
Protección
"#, "#,
/// End character window section /// End character window section
@ -418,9 +426,29 @@ Fuerza de Voluntad
"esc_menu.logout": "Cerrar Sesión", "esc_menu.logout": "Cerrar Sesión",
"esc_menu.quit_game": "Salir del Juego", "esc_menu.quit_game": "Salir del Juego",
/// End Escape Menu Section /// End Escape Menu Section
}
vector_map: { },
vector_map: {
"loading.tips": [
"Presiona 'G' para encender tu linterna.",
"Presiona 'F1' para ver los controles predeterminados.",
"Puedes escribir /say o /s para chatear solo con jugadores alrededor tuyo.",
"Puedes escribr /region o /r para chatear solo con jugadores que están a unos cien bloques alrededor tuyo.",
"Para enviar mensajes privados escribe /tell segudi de el nombre de un jugador y luego tu mensaje.",
"NPCs con el mismo nivel pueden tener una dificultad diferente.",
"Observa el terreno en búsqueda de comida, cofres y botines!",
"¿Inventario lleno de comida? Intenta craftear mejor comida con ella!",
"¿Te preguntas dónde debes hacerlo? Los Dungeons están marcados con puntos marrones en el mapa!",
"No te olvides de ajustar los gráficos de tu pc. Presiona 'N' para abrir la configuración.",
"Jugar con otros es divertido! Presiona 'O' para ver quien esta conectado.",
"Un NPC con una craneo debajo de su barra de vida es bastante más poderoso comparado contigo.",
"Presiona 'J' para bailar. Fiesta!",
"Presiona 'Shift-Izquierdo' para abrir tu planeador y conquistar los cielos.",
"Veloren está aún en Alfa temprana. Hacemos lo mejor para mejorar día a día!",
"Si te quieres unir al equipo de desarrolladores o solo chatear con nosotros, únete a nuestro servidor en Discord.",
],
"npc.speech.villager_under_attack": [ "npc.speech.villager_under_attack": [
"Ayuda, ¡Me están atacando!", "Ayuda, ¡Me están atacando!",
"¡Ayuda! ¡Me están atacando!", "¡Ayuda! ¡Me están atacando!",
@ -457,7 +485,50 @@ Fuerza de Voluntad
"¡Vienen por mi!", "¡Vienen por mi!",
"¡Ayuda! ¡Ayuda! Estoy siendo oprimido", "¡Ayuda! ¡Ayuda! Estoy siendo oprimido",
"Ah, se nota que la violencia es parte del sistema.", "Ah, se nota que la violencia es parte del sistema.",
"¡Esto no es más que un rasguño!" "¡Esto no es más que un rasguño!",
"Para con eso!",
"¿Qué te hice para merecer esto?",
"Por favor, para de atacarme!",
"Hey! Mira hacia adonde apuntas esa cosa",
"Desgraciado, vete de aqui!",
"Para ya! Vete!",
"Ahora me estas enfureciendo!",
"Hey!¿Quién te piensas que eres?",
"Te arrancaré la cabeza por eso!",
"Detente, por favor! No llevo nada de valor!",
"Te voy a mandar a mi hermano, el es más grande que yo!",
"Nooo, le contaré a mi madre!",
"Maldito seas!",
"Por favor no lo hagas.",
"Eso no fue agradable!",
"Tu arma sirve, ahora aléjala!",
"Si claro...",
"Por favor, tengo familia!",
"Soy demasiado jóven para morir!",
"¿Podemos hablar sobre esto?",
"La violencia no es el medio!",
"Este día se esta convirtiendo en uno muy feo...",
"Hey, eso dolió!",
"Ayy!",
"Qué violento!",
"Detente, te lo suplico!",
"Ojala te enfermes!",
"Esto no es divertido.",
"¡¿Cómo te atreves?!",
"Vas a pagar por eso!",
"Sigue con eso y lo lamentarás!",
"No hagas que te lastime!",
"Tiene que haber algun tipo de malentendido!",
"No necesitas hacer esto!",
"Vete, demonio!",
"Eso dolió realmente!",
"¿Por qué harias eso?",
"Por los espíritus, para!",
"Me habrás confudido con alguien más!",
"No me merezco esto!",
"Por favor, no lo hagas de nuevo",
"Guardias, tiren este monstruo al lago",
"Invocaré mis demonios en ti!",
], ],
} }
) )

View File

@ -461,11 +461,11 @@
(2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1, (2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1,
), ),
Tool(Hammer("CobaltHammer0")): VoxTrans( Tool(Hammer("CobaltHammer0")): VoxTrans(
"voxel.weapon.hammer.2hhammer_Cobalt-0", "voxel.weapon.hammer.2hhammer_cobalt-0",
(2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1, (2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1,
), ),
Tool(Hammer("CobaltHammer1")): VoxTrans( Tool(Hammer("CobaltHammer1")): VoxTrans(
"voxel.weapon.hammer.2hhammer_Cobalt-1", "voxel.weapon.hammer.2hhammer_cobalt-1",
(2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1, (2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1,
), ),
Tool(Hammer("RunicHammer")): VoxTrans( Tool(Hammer("RunicHammer")): VoxTrans(
@ -508,16 +508,16 @@
(0.0, 0.0, 0.0), (-90.0, 90.0, 0.0), 2.4, (0.0, 0.0, 0.0), (-90.0, 90.0, 0.0), 2.4,
), ),
// Lanterns // Lanterns
Lantern(Black0): Png( Lantern("Black0"): Png(
"element.icons.lantern_black-0", "element.icons.lantern_black-0",
), ),
Lantern(Green0): Png( Lantern("Green0"): Png(
"element.icons.lantern_green-0", "element.icons.lantern_green-0",
), ),
Lantern(Blue0): Png( Lantern("Blue0"): Png(
"element.icons.lantern_blue-0", "element.icons.lantern_blue-0",
), ),
Lantern(Red0): Png( Lantern("Red0"): Png(
"element.icons.lantern_red-0", "element.icons.lantern_red-0",
), ),
// Farming Equipment // Farming Equipment
@ -621,7 +621,7 @@
"voxel.armor.shoulder.cultist_right", "voxel.armor.shoulder.cultist_right",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
), ),
// Druid Set // Druid Set
Armor(Chest("Druid")): VoxTrans( Armor(Chest("Druid")): VoxTrans(
"voxel.armor.chest.druid", "voxel.armor.chest.druid",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
@ -762,7 +762,7 @@
"voxel.armor.hand.steel_right-0", "voxel.armor.hand.steel_right-0",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0, (0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
), ),
Armor(Shoulder("Steel0")): VoxTrans( Armor(Shoulder("Steel0")): VoxTrans(
"voxel.armor.shoulder.steel_right-0", "voxel.armor.shoulder.steel_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
@ -787,7 +787,7 @@
"voxel.armor.hand.leather_right-0", "voxel.armor.hand.leather_right-0",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0, (0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
), ),
Armor(Shoulder("Leather0")): VoxTrans( Armor(Shoulder("Leather0")): VoxTrans(
"voxel.armor.shoulder.leather_right-0", "voxel.armor.shoulder.leather_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
@ -817,7 +817,7 @@
"voxel.armor.hand.leather_right-2", "voxel.armor.hand.leather_right-2",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0, (0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
), ),
Armor(Shoulder("Leather2")): VoxTrans( Armor(Shoulder("Leather2")): VoxTrans(
"voxel.armor.shoulder.leather_right-2", "voxel.armor.shoulder.leather_right-2",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
@ -871,7 +871,7 @@
"voxel.armor.shoulder.cloth_green_right-0", "voxel.armor.shoulder.cloth_green_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
Armor(Shoulder("ClothGreen0")): VoxTrans( Armor(Shoulder("ClothGreen0")): VoxTrans(
"voxel.armor.shoulder.cloth_green_right-0", "voxel.armor.shoulder.cloth_green_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
@ -900,19 +900,19 @@
"voxel.armor.shoulder.cloth_purple_right-0", "voxel.armor.shoulder.cloth_purple_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
Armor(Shoulder("ClothBlue1")): VoxTrans( Armor(Shoulder("ClothBlue1")): VoxTrans(
"voxel.armor.shoulder.cloth_blue_right-1", "voxel.armor.shoulder.cloth_blue_right-1",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
Armor(Shoulder("IronSpikes")): VoxTrans( Armor(Shoulder("IronSpikes")): VoxTrans(
"voxel.armor.shoulder.iron_spikes_right", "voxel.armor.shoulder.iron_spikes_right",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
Armor(Shoulder("IronLeather3")): VoxTrans( Armor(Shoulder("IronLeather3")): VoxTrans(
"voxel.armor.shoulder.leather_iron_right-3", "voxel.armor.shoulder.leather_iron_right-3",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
Armor(Shoulder("IronLeather2")): VoxTrans( Armor(Shoulder("IronLeather2")): VoxTrans(
"voxel.armor.shoulder.leather_iron_right-2", "voxel.armor.shoulder.leather_iron_right-2",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
@ -978,7 +978,7 @@
"voxel.armor.hand.twigsleaves_glove_right", "voxel.armor.hand.twigsleaves_glove_right",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0, (0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
), ),
Armor(Shoulder("LeafyShoulder")): VoxTrans( Armor(Shoulder("LeafyShoulder")): VoxTrans(
"voxel.armor.shoulder.twigsleaves_shoulder_right", "voxel.armor.shoulder.twigsleaves_shoulder_right",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
@ -1003,7 +1003,7 @@
"voxel.armor.hand.twigsflowers_glove_right", "voxel.armor.hand.twigsflowers_glove_right",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0, (0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
), ),
Armor(Shoulder("FlowerShoulder")): VoxTrans( Armor(Shoulder("FlowerShoulder")): VoxTrans(
"voxel.armor.shoulder.twigsflowers_shoulder_right", "voxel.armor.shoulder.twigsflowers_shoulder_right",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2, (0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
), ),
@ -1047,55 +1047,54 @@
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.0, (0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.0,
), ),
// Consumables // Consumables
Consumable(Apple): Consumable("Apple"): Png(
Png(
"element.icons.item_apple", "element.icons.item_apple",
), ),
Consumable(Coconut): Png( Consumable("Coconut"): Png(
"element.icons.item_coconut", "element.icons.item_coconut",
), ),
Consumable(PotionMed): VoxTrans( Consumable("PotionMed"): VoxTrans(
"voxel.object.potion_red", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.7, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.7,
), ),
Consumable(PotionMinor): VoxTrans( Consumable("PotionMinor"): VoxTrans(
"voxel.object.potion_red", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.5, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.5,
), ),
Consumable(PotionLarge): VoxTrans( Consumable("PotionLarge"): VoxTrans(
"voxel.object.potion_red", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9,
), ),
Consumable(PotionExp): VoxTrans( Consumable("PotionExp"): VoxTrans(
"voxel.object.potion_turq", "voxel.object.potion_turq",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
), ),
Consumable(Cheese): Png( Consumable("Cheese"): Png(
"element.icons.item_cheese", "element.icons.item_cheese",
), ),
Consumable(Potion): VoxTrans( Consumable("Potion"): VoxTrans(
"voxel.object.potion_red", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.0, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.0,
), ),
Consumable(Mushroom): VoxTrans( Consumable("Mushroom"): VoxTrans(
"voxel.sprite.mushrooms.mushroom-10", "voxel.sprite.mushrooms.mushroom-10",
(0.0, 0.0, 0.0), (-50.0, 70.0, 40.0), 1.0, (0.0, 0.0, 0.0), (-50.0, 70.0, 40.0), 1.0,
), ),
Consumable(Velorite): VoxTrans( Consumable("Velorite"): VoxTrans(
"voxel.sprite.velorite.velorite_ore", "voxel.sprite.velorite.velorite_ore",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
), ),
Consumable(VeloriteFrag): VoxTrans( Consumable("VeloriteFrag"): VoxTrans(
"voxel.sprite.velorite.velorite_1", "voxel.sprite.velorite.velorite_1",
(0.0, 0.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, 0.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
), ),
Consumable(AppleShroomCurry): Png( Consumable("AppleShroomCurry"): Png(
"element.icons.item_apple_curry", "element.icons.item_apple_curry",
), ),
Consumable(AppleStick): Png( Consumable("AppleStick"): Png(
"element.icons.item_apple_stick", "element.icons.item_apple_stick",
), ),
Consumable(MushroomStick): Png( Consumable("MushroomStick"): Png(
"element.icons.item_shroom_stick", "element.icons.item_shroom_stick",
), ),
@ -1109,36 +1108,36 @@
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
), ),
// Ingredients // Ingredients
Ingredient(CraftsmanHammer): VoxTrans( //TODO This should be a 1h hammer! Ingredient("CraftsmanHammer"): VoxTrans( //TODO This should be a 1h hammer!
"voxel.weapon.hammer.craftsman", "voxel.weapon.hammer.craftsman",
(1.0, 1.0, 0.0), (-135.0, 90.0, 0.0), 1.0, (1.0, 1.0, 0.0), (-135.0, 90.0, 0.0), 1.0,
), ),
Ingredient(Flower): VoxTrans( Ingredient("Flower"): VoxTrans(
"voxel.sprite.flowers.flower_red_2", "voxel.sprite.flowers.flower_red_2",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
), ),
Ingredient(Grass): VoxTrans( Ingredient("Grass"): VoxTrans(
"voxel.sprite.grass.grass_long_5", "voxel.sprite.grass.grass_long_5",
(0.0, 0.0, 0.0), (-90.0, 50.0, 0.0), 1.0, (0.0, 0.0, 0.0), (-90.0, 50.0, 0.0), 1.0,
), ),
Ingredient(Stones): VoxTrans( Ingredient("Stones"): VoxTrans(
"voxel.sprite.rocks.rock-0", "voxel.sprite.rocks.rock-0",
(0.0, 0.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (0.0, 0.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
), ),
Ingredient(Twigs): VoxTrans( Ingredient("Twigs"): VoxTrans(
"voxel.sprite.twigs.twigs-0", "voxel.sprite.twigs.twigs-0",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
), ),
Ingredient(LeatherScraps): Png( Ingredient("LeatherScraps"): Png(
"element.icons.item_leather0", "element.icons.item_leather0",
), ),
Ingredient(ShinyGem): Png( Ingredient("ShinyGem"): Png(
"element.icons.gem", "element.icons.gem",
), ),
Ingredient(MortarPestle): Png( Ingredient("MortarPestle"): Png(
"element.icons.item_mortarpestlecoco", "element.icons.item_mortarpestlecoco",
), ),
Ingredient(EmptyVial): VoxTrans( Ingredient("EmptyVial"): VoxTrans(
"voxel.object.potion_empty", "voxel.object.potion_empty",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
), ),

View File

@ -143,4 +143,43 @@
center: ("armor.empty"), center: ("armor.empty"),
) )
), ),
(Dullahan, Male): (
head: (
offset: (-8.0, -5.0, -6.0),
center: ("armor.empty"),
),
torso_upper: (
offset: (-9.0, -7.5, -7.0),
center: ("npc.dullahan.male.torso_upper"),
),
torso_lower: (
offset: (-8.0, -6.0, -9.0),
center: ("npc.dullahan.male.torso_lower"),
),
main: (
offset: (-1.5, -9.0, -10.0),
center: ("npc.dullahan.male.sword"),
)
),
(Dullahan, Female): (
head: (
offset: (-8.0, -5.0, -6.0),
center: ("armor.empty"),
),
torso_upper: (
offset: (-9.0, -7.5, -7.0),
center: ("npc.dullahan.male.torso_upper"),
),
torso_lower: (
offset: (-8.0, -6.0, -9.0),
center: ("npc.dullahan.male.torso_lower"),
),
main: (
offset: (-1.5, -9.0, -10.0),
center: ("npc.dullahan.male.sword"),
)
),
}) })

View File

@ -31,7 +31,7 @@
foot_r: ( foot_r: (
offset: (-3.0, -5.0, -2.5), offset: (-3.0, -5.0, -2.5),
lateral: ("npc.ogre.male.foot_r"), lateral: ("npc.ogre.male.foot_r"),
) ),
), ),
(Ogre, Female): ( (Ogre, Female): (
shoulder_l: ( shoulder_l: (
@ -65,7 +65,7 @@
foot_r: ( foot_r: (
offset: (-3.0, -5.0, -2.5), offset: (-3.0, -5.0, -2.5),
lateral: ("npc.ogre.male.foot_r"), lateral: ("npc.ogre.male.foot_r"),
) ),
), ),
(Cyclops, Male): ( (Cyclops, Male): (
shoulder_l: ( shoulder_l: (
@ -99,7 +99,7 @@
foot_r: ( foot_r: (
offset: (-3.0, -5.0, -5.0), offset: (-3.0, -5.0, -5.0),
lateral: ("npc.cyclops.male.foot_r"), lateral: ("npc.cyclops.male.foot_r"),
) ),
), ),
(Cyclops, Female): ( (Cyclops, Female): (
shoulder_l: ( shoulder_l: (
@ -133,7 +133,7 @@
foot_r: ( foot_r: (
offset: (-3.0, -5.0, -5.0), offset: (-3.0, -5.0, -5.0),
lateral: ("npc.cyclops.male.foot_r"), lateral: ("npc.cyclops.male.foot_r"),
) ),
), ),
(Wendigo, Male): ( (Wendigo, Male): (
shoulder_l: ( shoulder_l: (
@ -167,7 +167,7 @@
foot_r: ( foot_r: (
offset: (-4.0, -5.0, -5.5), offset: (-4.0, -5.0, -5.5),
lateral: ("npc.wendigo.male.foot_r"), lateral: ("npc.wendigo.male.foot_r"),
) ),
), ),
(Wendigo, Female): ( (Wendigo, Female): (
shoulder_l: ( shoulder_l: (
@ -201,7 +201,7 @@
foot_r: ( foot_r: (
offset: (-4.0, -5.0, -5.5), offset: (-4.0, -5.0, -5.5),
lateral: ("npc.wendigo.male.foot_r"), lateral: ("npc.wendigo.male.foot_r"),
) ),
), ),
(Troll, Male): ( (Troll, Male): (
shoulder_l: ( shoulder_l: (
@ -235,7 +235,7 @@
foot_r: ( foot_r: (
offset: (-3.0, -5.0, -2.5), offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll.male.foot_r"), lateral: ("npc.troll.male.foot_r"),
) ),
), ),
(Troll, Female): ( (Troll, Female): (
shoulder_l: ( shoulder_l: (
@ -269,6 +269,74 @@
foot_r: ( foot_r: (
offset: (-3.0, -5.0, -2.5), offset: (-3.0, -5.0, -2.5),
lateral: ("npc.troll.male.foot_r"), lateral: ("npc.troll.male.foot_r"),
) ),
),
(Dullahan, Male): (
shoulder_l: (
offset: (-7.5, -5.5, -6.0),
lateral: ("npc.dullahan.male.shoulder_l"),
),
shoulder_r: (
offset: (-7.5, -5.5, -6.0),
lateral: ("npc.dullahan.male.shoulder_r"),
),
hand_l: (
offset: (-4.5, -4.5, -15.0),
lateral: ("npc.dullahan.male.hand_l"),
),
hand_r: (
offset: (-4.5, -4.5, -15.0),
lateral: ("npc.dullahan.male.hand_r"),
),
leg_l: (
offset: (-6.0, -3.0, -7.0),
lateral: ("npc.dullahan.male.leg_l"),
),
leg_r: (
offset: (0.0, -3.0, -7.0),
lateral: ("npc.dullahan.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -8.0),
lateral: ("npc.dullahan.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -8.0),
lateral: ("npc.dullahan.male.foot_r"),
),
),
(Dullahan, Female): (
shoulder_l: (
offset: (-7.5, -5.5, -6.0),
lateral: ("npc.dullahan.male.shoulder_l"),
),
shoulder_r: (
offset: (-7.5, -5.5, -6.0),
lateral: ("npc.dullahan.male.shoulder_r"),
),
hand_l: (
offset: (-4.5, -4.5, -15.0),
lateral: ("npc.dullahan.male.hand_l"),
),
hand_r: (
offset: (-4.5, -4.5, -15.0),
lateral: ("npc.dullahan.male.hand_r"),
),
leg_l: (
offset: (-6.0, -3.0, -7.0),
lateral: ("npc.dullahan.male.leg_l"),
),
leg_r: (
offset: (0.0, -3.0, -7.0),
lateral: ("npc.dullahan.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -8.0),
lateral: ("npc.dullahan.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -8.0),
lateral: ("npc.dullahan.male.foot_r"),
),
), ),
}) })

View File

@ -4,19 +4,19 @@
color: None color: None
), ),
map: { map: {
Green0: ( "Green0": (
vox_spec: ("armor.lantern.green-0", (-2.0, -2.0, -7.0)), vox_spec: ("armor.lantern.green-0", (-2.0, -2.0, -7.0)),
color: None color: None
), ),
Black0: ( "Black0": (
vox_spec: ("armor.lantern.black-0", (-2.0, -2.0, -7.0)), vox_spec: ("armor.lantern.black-0", (-2.0, -2.0, -7.0)),
color: None color: None
), ),
Red0: ( "Red0": (
vox_spec: ("armor.lantern.red-0", (-2.0, -2.0, -7.0)), vox_spec: ("armor.lantern.red-0", (-2.0, -2.0, -7.0)),
color: None color: None
), ),
Blue0: ( "Blue0": (
vox_spec: ("armor.lantern.blue-0", (-2.0, -2.0, -7.0)), vox_spec: ("armor.lantern.blue-0", (-2.0, -2.0, -7.0)),
color: None color: None
), ),

BIN
assets/voxygen/voxel/npc/dullahan/male/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/hand_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/hand_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/leg_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/leg_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/shoulder_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/shoulder_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/sword.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/torso_lower.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/dullahan/male/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -213,7 +213,7 @@ impl Body {
pub fn radius(&self) -> f32 { pub fn radius(&self) -> f32 {
// TODO: Improve these values (some might be reliant on more info in inner type) // TODO: Improve these values (some might be reliant on more info in inner type)
match self { match self {
Body::Humanoid(_) => 0.5, Body::Humanoid(_) => 0.2,
Body::QuadrupedSmall(_) => 0.3, Body::QuadrupedSmall(_) => 0.3,
Body::QuadrupedMedium(_) => 0.9, Body::QuadrupedMedium(_) => 0.9,
Body::Critter(_) => 0.2, Body::Critter(_) => 0.2,
@ -229,8 +229,29 @@ impl Body {
} }
} }
// Note: currently assumes sphericality pub fn height(&self) -> f32 {
pub fn height(&self) -> f32 { self.radius() * 2.0 } match self {
Body::Humanoid(humanoid) => match humanoid.species {
humanoid::Species::Danari => 0.8,
humanoid::Species::Dwarf => 0.9,
humanoid::Species::Orc => 1.14,
humanoid::Species::Undead => 0.95,
_ => 1.0,
},
Body::QuadrupedSmall(_) => 0.6,
Body::QuadrupedMedium(_) => 0.5,
Body::Critter(_) => 0.4,
Body::BirdMedium(_) => 1.2,
Body::FishMedium(_) => 1.0,
Body::Dragon(_) => 5.0,
Body::BirdSmall(_) => 0.4,
Body::FishSmall(_) => 0.4,
Body::BipedLarge(_) => 4.0,
Body::Golem(_) => 5.0,
Body::QuadrupedLow(_) => 0.5,
Body::Object(_) => 0.6,
}
}
pub fn base_health(&self) -> u32 { pub fn base_health(&self) -> u32 {
match self { match self {

View File

@ -32,6 +32,7 @@ pub enum Species {
Cyclops = 1, Cyclops = 1,
Wendigo = 2, Wendigo = 2,
Troll = 3, Troll = 3,
Dullahan = 4,
} }
/// Data representing per-species generic data. /// Data representing per-species generic data.
@ -43,6 +44,7 @@ pub struct AllSpecies<SpeciesMeta> {
pub cyclops: SpeciesMeta, pub cyclops: SpeciesMeta,
pub wendigo: SpeciesMeta, pub wendigo: SpeciesMeta,
pub troll: SpeciesMeta, pub troll: SpeciesMeta,
pub dullahan: SpeciesMeta,
} }
impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> { impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
@ -55,15 +57,17 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
Species::Cyclops => &self.cyclops, Species::Cyclops => &self.cyclops,
Species::Wendigo => &self.wendigo, Species::Wendigo => &self.wendigo,
Species::Troll => &self.troll, Species::Troll => &self.troll,
Species::Dullahan => &self.dullahan,
} }
} }
} }
pub const ALL_SPECIES: [Species; 4] = [ pub const ALL_SPECIES: [Species; 5] = [
Species::Ogre, Species::Ogre,
Species::Cyclops, Species::Cyclops,
Species::Wendigo, Species::Wendigo,
Species::Troll, Species::Troll,
Species::Dullahan,
]; ];
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> { impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {

View File

@ -16,24 +16,6 @@ use specs_idvs::IdvStorage;
use std::{fs::File, io::BufReader}; use std::{fs::File, io::BufReader};
use vek::Rgb; use vek::Rgb;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Consumable {
Coconut,
Apple,
Cheese,
Potion,
Mushroom,
Velorite,
VeloriteFrag,
PotionMinor,
PotionMed,
PotionLarge,
PotionExp,
AppleShroomCurry,
AppleStick,
MushroomStick,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Throwable { pub enum Throwable {
Bomb, Bomb,
@ -45,43 +27,14 @@ pub enum Utility {
Collar, Collar,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Ingredient {
Flower,
Grass,
EmptyVial,
LeatherScraps,
ShinyGem,
Stones,
Twigs,
MortarPestle,
CraftsmanHammer,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum LanternKind {
Black0 = 1,
Green0 = 2,
Red0 = 3,
Blue0 = 4,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Lantern { pub struct Lantern {
pub kind: LanternKind, pub kind: String,
color: Rgb<u32>, color: Rgb<u32>,
strength_thousandths: u32, strength_thousandths: u32,
flicker_thousandths: u32, flicker_thousandths: u32,
} }
pub const ALL_LANTERNS: [LanternKind; 4] = [
LanternKind::Black0,
LanternKind::Green0,
LanternKind::Red0,
LanternKind::Blue0,
];
impl Lantern { impl Lantern {
pub fn strength(&self) -> f32 { self.strength_thousandths as f32 / 1000_f32 } pub fn strength(&self) -> f32 { self.strength_thousandths as f32 / 1000_f32 }
@ -97,7 +50,7 @@ pub enum ItemKind {
Lantern(Lantern), Lantern(Lantern),
Armor(armor::Armor), Armor(armor::Armor),
Consumable { Consumable {
kind: Consumable, kind: String,
effect: Effect, effect: Effect,
#[serde(default = "default_amount")] #[serde(default = "default_amount")]
amount: u32, amount: u32,
@ -113,7 +66,7 @@ pub enum ItemKind {
amount: u32, amount: u32,
}, },
Ingredient { Ingredient {
kind: Ingredient, kind: String,
#[serde(default = "default_amount")] #[serde(default = "default_amount")]
amount: u32, amount: u32,
}, },

View File

@ -142,7 +142,7 @@ impl Tool {
recover_duration: Duration::from_millis(300), recover_duration: Duration::from_millis(300),
base_healthchange: (-120.0 * self.base_power()) as i32, base_healthchange: (-120.0 * self.base_power()) as i32,
range: 3.5, range: 3.5,
max_angle: 60.0, max_angle: 20.0,
}, },
LeapMelee { LeapMelee {
energy_cost: 800, energy_cost: 800,
@ -157,8 +157,8 @@ impl Tool {
buildup_duration: Duration::from_millis(700), buildup_duration: Duration::from_millis(700),
recover_duration: Duration::from_millis(150), recover_duration: Duration::from_millis(150),
base_healthchange: (-50.0 * self.base_power()) as i32, base_healthchange: (-50.0 * self.base_power()) as i32,
range: 3.0, range: 3.5,
max_angle: 60.0, max_angle: 20.0,
}], }],
Bow(_) => vec![ Bow(_) => vec![
BasicRanged { BasicRanged {
@ -171,7 +171,7 @@ impl Tool {
hit_entity: vec![ hit_entity: vec![
projectile::Effect::Damage((-40.0 * self.base_power()) as i32), projectile::Effect::Damage((-40.0 * self.base_power()) as i32),
projectile::Effect::Knockback(10.0), projectile::Effect::Knockback(10.0),
projectile::Effect::RewardEnergy(100), projectile::Effect::RewardEnergy(50),
projectile::Effect::Vanish, projectile::Effect::Vanish,
], ],
time_left: Duration::from_secs(15), time_left: Duration::from_secs(15),
@ -202,7 +202,7 @@ impl Tool {
recover_duration: Duration::from_millis(400), recover_duration: Duration::from_millis(400),
base_healthchange: (-50.0 * self.base_power()) as i32, base_healthchange: (-50.0 * self.base_power()) as i32,
range: 3.5, range: 3.5,
max_angle: 60.0, max_angle: 20.0,
}, },
DashMelee { DashMelee {
energy_cost: 700, energy_cost: 700,
@ -219,8 +219,8 @@ impl Tool {
buildup_duration: Duration::from_millis(0), buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(300), recover_duration: Duration::from_millis(300),
base_healthchange: (-10.0 * self.base_power()) as i32, base_healthchange: (-10.0 * self.base_power()) as i32,
range: 10.0, range: 5.0,
max_angle: 45.0, max_angle: 20.0,
}, },
BasicMelee { BasicMelee {
energy_cost: 350, energy_cost: 350,
@ -238,8 +238,8 @@ impl Tool {
buildup_duration: Duration::from_millis(100), buildup_duration: Duration::from_millis(100),
recover_duration: Duration::from_millis(300), recover_duration: Duration::from_millis(300),
base_healthchange: (-40.0 * self.base_power()) as i32, base_healthchange: (-40.0 * self.base_power()) as i32,
range: 10.0, range: 3.5,
max_angle: 45.0, max_angle: 20.0,
}, },
BasicRanged { BasicRanged {
energy_cost: 0, energy_cost: 0,
@ -261,7 +261,6 @@ impl Tool {
col: (0.85, 0.5, 0.11).into(), col: (0.85, 0.5, 0.11).into(),
..Default::default() ..Default::default()
}), }),
projectile_gravity: None, projectile_gravity: None,
}, },
BasicRanged { BasicRanged {
@ -349,8 +348,8 @@ impl Tool {
buildup_duration: Duration::from_millis(0), buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(1000), recover_duration: Duration::from_millis(1000),
base_healthchange: -20, base_healthchange: -20,
range: 5.0, range: 3.5,
max_angle: 60.0, max_angle: 15.0,
}], }],
} }
} }

View File

@ -2,7 +2,7 @@ pub mod item;
pub mod slot; pub mod slot;
use crate::{assets, recipe::Recipe}; use crate::{assets, recipe::Recipe};
use item::{Consumable, Item, ItemKind}; use item::{Item, ItemKind};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage, HashMapStorage}; use specs::{Component, FlaggedStorage, HashMapStorage};
use specs_idvs::IdvStorage; use specs_idvs::IdvStorage;
@ -38,7 +38,7 @@ impl Inventory {
/// Adds a new item to the first fitting group of the inventory or starts a /// Adds a new item to the first fitting group of the inventory or starts a
/// new group. Returns the item again if no space was found. /// new group. Returns the item again if no space was found.
pub fn push(&mut self, item: Item) -> Option<Item> { pub fn push(&mut self, item: Item) -> Option<Item> {
let item = match item.kind { let item = match &item.kind {
ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Lantern(_) => { ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Lantern(_) => {
self.add_to_first_empty(item) self.add_to_first_empty(item)
}, },
@ -61,7 +61,7 @@ impl Inventory {
.. ..
}) = slot }) = slot
{ {
if item_kind == *kind { if *item_kind == *kind {
*amount += new_amount; *amount += new_amount;
self.recount_items(); self.recount_items();
return None; return None;
@ -92,7 +92,7 @@ impl Inventory {
.. ..
}) = slot }) = slot
{ {
if item_kind == *kind { if *item_kind == *kind {
*amount += new_amount; *amount += new_amount;
self.recount_items(); self.recount_items();
return None; return None;
@ -123,7 +123,7 @@ impl Inventory {
.. ..
}) = slot }) = slot
{ {
if item_kind == *kind { if *item_kind == *kind {
*amount += new_amount; *amount += new_amount;
self.recount_items(); self.recount_items();
return None; return None;
@ -153,7 +153,7 @@ impl Inventory {
.. ..
}) = slot }) = slot
{ {
if item_kind == *kind { if *item_kind == *kind {
*amount += new_amount; *amount += new_amount;
self.recount_items(); self.recount_items();
return None; return None;
@ -424,7 +424,7 @@ impl Inventory {
} else { } else {
*amount -= 1; *amount -= 1;
return_item.kind = ItemKind::Consumable { return_item.kind = ItemKind::Consumable {
kind: *kind, kind: kind.clone(),
effect: *effect, effect: *effect,
amount: 1, amount: 1,
}; };
@ -451,7 +451,7 @@ impl Inventory {
} else { } else {
*amount -= 1; *amount -= 1;
return_item.kind = ItemKind::Ingredient { return_item.kind = ItemKind::Ingredient {
kind: *kind, kind: kind.clone(),
amount: 1, amount: 1,
}; };
self.recount_items(); self.recount_items();
@ -531,7 +531,7 @@ impl Component for Inventory {
pub enum InventoryUpdateEvent { pub enum InventoryUpdateEvent {
Init, Init,
Used, Used,
Consumed(Consumable), Consumed(String),
Gave, Gave,
Given, Given,
Swapped, Swapped,

View File

@ -73,7 +73,7 @@ impl LoadoutBuilder {
recover_duration: Duration::from_millis(100), recover_duration: Duration::from_millis(100),
base_healthchange: -(body.base_dmg() as i32), base_healthchange: -(body.base_dmg() as i32),
range: body.base_range(), range: body.base_range(),
max_angle: 80.0, max_angle: 20.0,
}), }),
ability2: None, ability2: None,
ability3: None, ability3: None,

View File

@ -85,7 +85,7 @@ impl CharacterBehavior for Data {
if let Some(attack) = data.attacking { if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 { if attack.applied && attack.hit_count > 0 {
data.updater.remove::<Attacking>(data.entity); data.updater.remove::<Attacking>(data.entity);
update.energy.change_by(100, EnergySource::HitEnemy); update.energy.change_by(50, EnergySource::HitEnemy);
} }
} }

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
comp::{Attacking, CharacterState, EnergySource, StateUpdate}, comp::{Attacking, CharacterState, StateUpdate},
states::utils::*, states::utils::*,
sys::character_behavior::*, sys::character_behavior::*,
}; };
@ -57,7 +57,7 @@ impl CharacterBehavior for Data {
data.updater.insert(data.entity, Attacking { data.updater.insert(data.entity, Attacking {
base_healthchange: -(self.base_damage as i32), base_healthchange: -(self.base_damage as i32),
range: 3.5, range: 3.5,
max_angle: 180_f32.to_radians(), max_angle: 45_f32.to_radians(),
applied: false, applied: false,
hit_count: 0, hit_count: 0,
knockback: 0.0, knockback: 0.0,
@ -90,14 +90,6 @@ impl CharacterBehavior for Data {
data.updater.remove::<Attacking>(data.entity); data.updater.remove::<Attacking>(data.entity);
} }
// Grant energy on successful hit
if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 {
data.updater.remove::<Attacking>(data.entity);
update.energy.change_by(100, EnergySource::HitEnemy);
}
}
update update
} }
} }

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
comp::{Attacking, CharacterState, EnergySource, StateUpdate}, comp::{Attacking, CharacterState, StateUpdate},
states::utils::*, states::utils::*,
sys::character_behavior::*, sys::character_behavior::*,
}; };
@ -110,14 +110,6 @@ impl CharacterBehavior for Data {
data.updater.remove::<Attacking>(data.entity); data.updater.remove::<Attacking>(data.entity);
} }
// Grant energy on successful hit
if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 {
data.updater.remove::<Attacking>(data.entity);
update.energy.change_by(100, EnergySource::HitEnemy);
}
}
update update
} }
} }

View File

@ -133,14 +133,6 @@ impl CharacterBehavior for Data {
data.updater.remove::<Attacking>(data.entity); data.updater.remove::<Attacking>(data.entity);
} }
// Grant energy on successful hit
if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 {
data.updater.remove::<Attacking>(data.entity);
update.energy.change_by(10, EnergySource::HitEnemy);
}
}
update update
} }
} }

View File

@ -70,6 +70,8 @@ impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate { fn behavior(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data); let mut update = StateUpdate::from(data);
handle_move(data, &mut update, 0.3);
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587 #[allow(clippy::or_fun_call)] // TODO: Pending review in #587
let stage_time_active = self let stage_time_active = self
.stage_time_active .stage_time_active
@ -109,16 +111,6 @@ impl CharacterBehavior for Data {
}, },
}; };
// Handle hit applied
if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 {
// Take energy on successful hit
update.energy.change_by(100, EnergySource::HitEnemy);
// Always remove component
data.updater.remove::<Attacking>(data.entity);
}
}
// Handling movement // Handling movement
if stage_time_active < Duration::from_millis(STAGE_DURATION / 3) { if stage_time_active < Duration::from_millis(STAGE_DURATION / 3) {
let adjusted_accel = match (self.stage, data.physics.touch_entity.is_none()) { let adjusted_accel = match (self.stage, data.physics.touch_entity.is_none()) {
@ -130,12 +122,7 @@ impl CharacterBehavior for Data {
// Move player forward while in first third of each stage // Move player forward while in first third of each stage
if update.vel.0.magnitude_squared() < BASE_SPEED.powf(2.0) { if update.vel.0.magnitude_squared() < BASE_SPEED.powf(2.0) {
update.vel.0 += data.dt.0 update.vel.0 += data.dt.0 * (adjusted_accel * Vec3::from(data.ori.0.xy()));
* (if data.physics.on_ground {
Vec3::new(0.0, 0.0, 500.0) // Jump upwards if on ground
} else {
Vec3::one()
} + adjusted_accel * Vec3::from(data.ori.0.xy()));
let mag2 = update.vel.0.magnitude_squared(); let mag2 = update.vel.0.magnitude_squared();
if mag2 > BASE_SPEED.powf(2.0) { if mag2 > BASE_SPEED.powf(2.0) {
update.vel.0 = update.vel.0.normalized() * BASE_SPEED; update.vel.0 = update.vel.0.normalized() * BASE_SPEED;
@ -155,14 +142,16 @@ impl CharacterBehavior for Data {
Stage::Third => (self.base_damage as f32 * 1.5) as u32, Stage::Third => (self.base_damage as f32 * 1.5) as u32,
}; };
update.vel.0 = Vec3::new(data.inputs.move_dir.x, data.inputs.move_dir.y, 0.0) * 5.0;
// Try to deal damage in second half of stage // Try to deal damage in second half of stage
data.updater.insert(data.entity, Attacking { data.updater.insert(data.entity, Attacking {
base_healthchange: -(dmg as i32), base_healthchange: -(dmg as i32),
range: 3.5, range: 3.5,
max_angle: 180_f32.to_radians(), max_angle: 45_f32.to_radians(),
applied: false, applied: false,
hit_count: 0, hit_count: 0,
knockback: 16.0, knockback: 10.0,
}); });
CharacterState::TripleStrike(Data { CharacterState::TripleStrike(Data {
@ -187,6 +176,8 @@ impl CharacterBehavior for Data {
// Player messed up inputs, don't transition // Player messed up inputs, don't transition
else { None }; else { None };
update.vel.0 = Vec3::new(data.inputs.move_dir.x, data.inputs.move_dir.y, 0.0) * 5.0;
if let Some(stage) = next_stage { if let Some(stage) = next_stage {
CharacterState::TripleStrike(Data { CharacterState::TripleStrike(Data {
base_damage: self.base_damage, base_damage: self.base_damage,
@ -220,7 +211,7 @@ impl CharacterBehavior for Data {
if let Some(attack) = data.attacking { if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 { if attack.applied && attack.hit_count > 0 {
data.updater.remove::<Attacking>(data.entity); data.updater.remove::<Attacking>(data.entity);
update.energy.change_by(100, EnergySource::HitEnemy); update.energy.change_by(50, EnergySource::HitEnemy);
} }
} }

View File

@ -471,7 +471,7 @@ impl<'a> System<'a> for Sys {
let diff = Vec2::<f32>::from(pos.0 - pos_other.0); let diff = Vec2::<f32>::from(pos.0 - pos_other.0);
let collision_dist = 0.95 * (scale + scale_other); let collision_dist = 0.55 * (scale + scale_other);
if diff.magnitude_squared() > 0.0 if diff.magnitude_squared() > 0.0
&& diff.magnitude_squared() < collision_dist.powf(2.0) && diff.magnitude_squared() < collision_dist.powf(2.0)

View File

@ -24,12 +24,12 @@ pub fn handle_lantern(server: &mut Server, entity: EcsEntity) {
.write_storage::<comp::LightEmitter>() .write_storage::<comp::LightEmitter>()
.remove(entity); .remove(entity);
} else { } else {
let lantern_opt = ecs let loadout_storage = ecs.read_storage::<comp::Loadout>();
.read_storage::<comp::Loadout>() let lantern_opt = loadout_storage
.get(entity) .get(entity)
.and_then(|loadout| loadout.lantern.as_ref()) .and_then(|loadout| loadout.lantern.as_ref())
.and_then(|item| { .and_then(|item| {
if let comp::item::ItemKind::Lantern(l) = item.kind { if let comp::item::ItemKind::Lantern(l) = &item.kind {
Some(l) Some(l)
} else { } else {
None None

View File

@ -157,7 +157,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
match &item.kind { match &item.kind {
ItemKind::Consumable { kind, effect, .. } => { ItemKind::Consumable { kind, effect, .. } => {
maybe_effect = Some(*effect); maybe_effect = Some(*effect);
Some(comp::InventoryUpdateEvent::Consumed(*kind)) Some(comp::InventoryUpdateEvent::Consumed(kind.clone()))
}, },
ItemKind::Throwable { kind, .. } => { ItemKind::Throwable { kind, .. } => {
if let Some(pos) = if let Some(pos) =

View File

@ -0,0 +1 @@
-- This file should undo anything in `up.sql`

View File

@ -0,0 +1,17 @@
-- Delete invalid data caused by inconsistent enforcement of foreign key constraints.
DELETE FROM stats
WHERE NOT EXISTS (SELECT 1 FROM character WHERE character.id = stats.character_id);
DELETE FROM body
WHERE NOT EXISTS (SELECT 1 FROM character WHERE character.id = body.character_id);
DELETE FROM inventory
WHERE NOT EXISTS (SELECT 1 FROM character WHERE character.id = inventory.character_id);
DELETE FROM loadout
WHERE NOT EXISTS (SELECT 1 FROM character WHERE character.id = loadout.character_id);
-- Fix up incorrect skill data.
UPDATE stats
SET skills = json('{"skill_groups":[],"skills":[]}')
WHERE skills = json('""');

View File

@ -234,7 +234,7 @@ impl Drop for CharacterLoader {
/// After first logging in, and after a character is selected, we fetch this /// After first logging in, and after a character is selected, we fetch this
/// data for the purpose of inserting their persisted data for the entity. /// data for the purpose of inserting their persisted data for the entity.
fn load_character_data(player_uuid: &str, character_id: i32, db_dir: &str) -> CharacterDataResult { fn load_character_data(player_uuid: &str, character_id: i32, db_dir: &str) -> CharacterDataResult {
let connection = establish_connection(db_dir); let connection = establish_connection(db_dir)?;
let result = schema::character::dsl::character let result = schema::character::dsl::character
.filter(schema::character::id.eq(character_id)) .filter(schema::character::id.eq(character_id))
@ -281,7 +281,7 @@ fn load_character_list(player_uuid: &str, db_dir: &str) -> CharacterListResult {
.inner_join(schema::body::table) .inner_join(schema::body::table)
.inner_join(schema::stats::table) .inner_join(schema::stats::table)
.inner_join(schema::loadout::table) .inner_join(schema::loadout::table)
.load::<(Character, Body, Stats, Loadout)>(&establish_connection(db_dir)); .load::<(Character, Body, Stats, Loadout)>(&establish_connection(db_dir)?);
match result { match result {
Ok(data) => Ok(data Ok(data) => Ok(data
@ -322,7 +322,7 @@ fn create_character(
) -> CharacterListResult { ) -> CharacterListResult {
check_character_limit(uuid, db_dir)?; check_character_limit(uuid, db_dir)?;
let connection = establish_connection(db_dir); let connection = establish_connection(db_dir)?;
connection.transaction::<_, diesel::result::Error, _>(|| { connection.transaction::<_, diesel::result::Error, _>(|| {
use schema::{body, character, character::dsl::*, inventory, loadout, stats}; use schema::{body, character, character::dsl::*, inventory, loadout, stats};
@ -413,12 +413,20 @@ fn create_character(
fn delete_character(uuid: &str, character_id: i32, db_dir: &str) -> CharacterListResult { fn delete_character(uuid: &str, character_id: i32, db_dir: &str) -> CharacterListResult {
use schema::character::dsl::*; use schema::character::dsl::*;
diesel::delete( let connection = establish_connection(db_dir)?;
character
.filter(id.eq(character_id)) if let Err(e) = connection.transaction::<_, diesel::result::Error, _>(|| {
.filter(player_uuid.eq(uuid)), diesel::delete(
) character
.execute(&establish_connection(db_dir))?; .filter(id.eq(character_id))
.filter(player_uuid.eq(uuid)),
)
.execute(&connection)?;
Ok(())
}) {
error!(?e, "Error during stats batch update transaction");
}
load_character_list(uuid, db_dir) load_character_list(uuid, db_dir)
} }
@ -432,7 +440,7 @@ fn check_character_limit(uuid: &str, db_dir: &str) -> Result<(), Error> {
let character_count = character let character_count = character
.select(count_star()) .select(count_star())
.filter(player_uuid.eq(uuid)) .filter(player_uuid.eq(uuid))
.load::<i64>(&establish_connection(db_dir))?; .load::<i64>(&establish_connection(db_dir)?)?;
match character_count.first() { match character_count.first() {
Some(count) => { Some(count) => {
@ -511,25 +519,28 @@ impl CharacterUpdater {
fn batch_update(updates: impl Iterator<Item = (i32, CharacterUpdateData)>, db_dir: &str) { fn batch_update(updates: impl Iterator<Item = (i32, CharacterUpdateData)>, db_dir: &str) {
let connection = establish_connection(db_dir); let connection = establish_connection(db_dir);
if let Err(e) = connection.transaction::<_, diesel::result::Error, _>(|| { if let Err(e) = connection.and_then(|connection| {
updates.for_each( connection.transaction::<_, diesel::result::Error, _>(|| {
|(character_id, (stats_update, inventory_update, loadout_update))| { updates.for_each(
update( |(character_id, (stats_update, inventory_update, loadout_update))| {
character_id, update(
&stats_update, character_id,
&inventory_update, &stats_update,
&loadout_update, &inventory_update,
&connection, &loadout_update,
) &connection,
}, )
); },
);
Ok(()) Ok(())
})
}) { }) {
error!(?e, "Error during stats batch update transaction"); error!(?e, "Error during stats batch update transaction");
} }
} }
/// NOTE: Only call while a transaction is held!
fn update( fn update(
character_id: i32, character_id: i32,
stats: &StatsUpdate, stats: &StatsUpdate,

View File

@ -31,10 +31,16 @@ embed_migrations!();
pub fn run_migrations(db_dir: &str) -> Result<(), diesel_migrations::RunMigrationsError> { pub fn run_migrations(db_dir: &str) -> Result<(), diesel_migrations::RunMigrationsError> {
let db_dir = &apply_saves_dir_override(db_dir); let db_dir = &apply_saves_dir_override(db_dir);
let _ = fs::create_dir(format!("{}/", db_dir)); let _ = fs::create_dir(format!("{}/", db_dir));
embedded_migrations::run_with_output(&establish_connection(db_dir), &mut std::io::stdout()) embedded_migrations::run_with_output(
&establish_connection(db_dir).expect(
"If we cannot execute migrations, we should not be allowed to launch the server, so \
we don't populate it with bad data.",
),
&mut std::io::stdout(),
)
} }
fn establish_connection(db_dir: &str) -> SqliteConnection { fn establish_connection(db_dir: &str) -> QueryResult<SqliteConnection> {
let db_dir = &apply_saves_dir_override(db_dir); let db_dir = &apply_saves_dir_override(db_dir);
let database_url = format!("{}/db.sqlite", db_dir); let database_url = format!("{}/db.sqlite", db_dir);
@ -45,18 +51,21 @@ fn establish_connection(db_dir: &str) -> SqliteConnection {
// Set a busy timeout (in ms): https://sqlite.org/c3ref/busy_timeout.html // Set a busy timeout (in ms): https://sqlite.org/c3ref/busy_timeout.html
if let Err(e) = connection.batch_execute( if let Err(e) = connection.batch_execute(
" "
PRAGMA foreign_keys = ON;
PRAGMA journal_mode = WAL; PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 250; PRAGMA busy_timeout = 250;
", ",
) { ) {
warn!( warn!(
?e, ?e,
"Failed adding PRAGMA statements while establishing sqlite connection, this will \ "Failed adding PRAGMA statements while establishing sqlite connection, including \
result in a higher likelihood of locking errors" enabling foreign key constraints. We will not allow connecting to the server under \
these conditions."
); );
return Err(e);
} }
connection Ok(connection)
} }
fn apply_saves_dir_override(db_dir: &str) -> String { fn apply_saves_dir_override(db_dir: &str) -> String {

View File

@ -137,9 +137,9 @@ impl<'a> System<'a> for Sys {
energy_cost: 0, energy_cost: 0,
buildup_duration: Duration::from_millis(0), buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(400), recover_duration: Duration::from_millis(400),
base_healthchange: -60, base_healthchange: -40,
range: 5.0, range: 3.5,
max_angle: 80.0, max_angle: 15.0,
}), }),
ability2: None, ability2: None,
ability3: None, ability3: None,

View File

@ -111,42 +111,49 @@ impl<'a> From<&'a comp::biped_large::Body> for SkeletonAttr {
(Cyclops, _) => (4.5, 7.5), (Cyclops, _) => (4.5, 7.5),
(Wendigo, _) => (3.0, 13.5), (Wendigo, _) => (3.0, 13.5),
(Troll, _) => (6.0, 10.0), (Troll, _) => (6.0, 10.0),
(Dullahan, _) => (3.0, 6.0),
}, },
upper_torso: match (body.species, body.body_type) { upper_torso: match (body.species, body.body_type) {
(Ogre, _) => (0.0, 19.0), (Ogre, _) => (0.0, 19.0),
(Cyclops, _) => (-2.0, 27.0), (Cyclops, _) => (-2.0, 27.0),
(Wendigo, _) => (-1.0, 29.0), (Wendigo, _) => (-1.0, 29.0),
(Troll, _) => (-1.0, 27.5), (Troll, _) => (-1.0, 27.5),
(Dullahan, _) => (0.0, 29.0),
}, },
lower_torso: match (body.species, body.body_type) { lower_torso: match (body.species, body.body_type) {
(Ogre, _) => (1.0, -5.5), (Ogre, _) => (1.0, -5.5),
(Cyclops, _) => (1.0, -4.5), (Cyclops, _) => (1.0, -4.5),
(Wendigo, _) => (-1.5, -6.0), (Wendigo, _) => (-1.5, -6.0),
(Troll, _) => (1.0, -10.5), (Troll, _) => (1.0, -10.5),
(Dullahan, _) => (0.0, -6.5),
}, },
shoulder: match (body.species, body.body_type) { shoulder: match (body.species, body.body_type) {
(Ogre, _) => (6.1, 0.5, 2.5), (Ogre, _) => (6.1, 0.5, 2.5),
(Cyclops, _) => (9.5, 2.5, 2.5), (Cyclops, _) => (9.5, 2.5, 2.5),
(Wendigo, _) => (9.0, 0.5, -0.5), (Wendigo, _) => (9.0, 0.5, -0.5),
(Troll, _) => (11.0, 0.5, -2.5), (Troll, _) => (11.0, 0.5, -2.5),
(Dullahan, _) => (14.0, 0.5, 4.5),
}, },
hand: match (body.species, body.body_type) { hand: match (body.species, body.body_type) {
(Ogre, _) => (10.5, -1.0, -0.5), (Ogre, _) => (10.5, -1.0, -0.5),
(Cyclops, _) => (10.0, 2.0, -0.5), (Cyclops, _) => (10.0, 2.0, -0.5),
(Wendigo, _) => (12.0, 0.0, -0.5), (Wendigo, _) => (12.0, 0.0, -0.5),
(Troll, _) => (11.5, 0.0, -1.5), (Troll, _) => (11.5, 0.0, -1.5),
(Dullahan, _) => (14.5, 0.0, -2.5),
}, },
leg: match (body.species, body.body_type) { leg: match (body.species, body.body_type) {
(Ogre, _) => (0.0, 0.0, 0.0), (Ogre, _) => (0.0, 0.0, 0.0),
(Cyclops, _) => (0.0, 0.0, -5.0), (Cyclops, _) => (0.0, 0.0, -5.0),
(Wendigo, _) => (2.0, 2.0, -2.5), (Wendigo, _) => (2.0, 2.0, -2.5),
(Troll, _) => (5.0, 0.0, -6.0), (Troll, _) => (5.0, 0.0, -6.0),
(Dullahan, _) => (0.0, 0.0, -5.0),
}, },
foot: match (body.species, body.body_type) { foot: match (body.species, body.body_type) {
(Ogre, _) => (4.0, 2.5, 2.5), (Ogre, _) => (4.0, 2.5, 2.5),
(Cyclops, _) => (4.0, 0.5, 5.0), (Cyclops, _) => (4.0, 0.5, 5.0),
(Wendigo, _) => (5.0, 0.5, 6.0), (Wendigo, _) => (5.0, 0.5, 6.0),
(Troll, _) => (6.0, 0.5, 4.0), (Troll, _) => (6.0, 0.5, 4.0),
(Dullahan, _) => (4.0, 2.5, 8.0),
}, },
} }
} }

View File

@ -21,6 +21,8 @@ impl Animation for JumpAnimation {
) -> Self::Skeleton { ) -> Self::Skeleton {
let mut next = (*skeleton).clone(); let mut next = (*skeleton).clone();
let wave = (_anim_time as f32 * 1.0).sin();
next.head.position = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1); next.head.position = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1);
next.head.orientation = Quaternion::rotation_z(0.8) * Quaternion::rotation_x(0.5); next.head.orientation = Quaternion::rotation_z(0.8) * Quaternion::rotation_x(0.5);
next.head.scale = Vec3::one(); next.head.scale = Vec3::one();
@ -30,11 +32,11 @@ impl Animation for JumpAnimation {
next.chest.scale = Vec3::one() / 18.0; next.chest.scale = Vec3::one() / 18.0;
next.feet_f.position = Vec3::new(0.0, skeleton_attr.feet_f.0, skeleton_attr.feet_f.1); next.feet_f.position = Vec3::new(0.0, skeleton_attr.feet_f.0, skeleton_attr.feet_f.1);
next.feet_f.orientation = Quaternion::rotation_z(0.0); next.feet_f.orientation = Quaternion::rotation_x(wave * 0.4);
next.feet_f.scale = Vec3::one(); next.feet_f.scale = Vec3::one();
next.feet_b.position = Vec3::new(0.0, skeleton_attr.feet_b.0, skeleton_attr.feet_b.1); next.feet_b.position = Vec3::new(0.0, skeleton_attr.feet_b.0, skeleton_attr.feet_b.1);
next.feet_b.orientation = Quaternion::rotation_x(0.0); next.feet_b.orientation = Quaternion::rotation_x(wave * 0.4);
next.feet_b.scale = Vec3::one(); next.feet_b.scale = Vec3::one();
next.tail.position = Vec3::new(0.0, skeleton_attr.tail.0, skeleton_attr.tail.1); next.tail.position = Vec3::new(0.0, skeleton_attr.tail.0, skeleton_attr.tail.1);

View File

@ -22,8 +22,8 @@ impl Animation for RunAnimation {
) -> Self::Skeleton { ) -> Self::Skeleton {
let mut next = (*skeleton).clone(); let mut next = (*skeleton).clone();
let wave = (anim_time as f32 * 13.0).sin(); let wave = (anim_time as f32 * 8.0).sin();
let wave_cos = (anim_time as f32 * 13.0).sin(); let wavealt = (anim_time as f32 * 8.0 + PI / 2.0).sin();
let wave_slow = (anim_time as f32 * 6.5 + PI).sin(); let wave_slow = (anim_time as f32 * 6.5 + PI).sin();
next.head.position = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1); next.head.position = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1);
@ -36,15 +36,17 @@ impl Animation for RunAnimation {
skeleton_attr.chest.0 + wave * 1.0, skeleton_attr.chest.0 + wave * 1.0,
skeleton_attr.chest.1, skeleton_attr.chest.1,
) / 18.0; ) / 18.0;
next.chest.orientation = Quaternion::rotation_y(0.0); next.chest.orientation = Quaternion::rotation_x(wave * 0.1);
next.chest.scale = Vec3::one() / 18.0; next.chest.scale = Vec3::one() / 18.0;
next.feet_f.position = Vec3::new(0.0, skeleton_attr.feet_f.0, skeleton_attr.feet_f.1); next.feet_f.position = Vec3::new(0.0, skeleton_attr.feet_f.0, skeleton_attr.feet_f.1);
next.feet_f.orientation = Quaternion::rotation_x(wave * 1.0); next.feet_f.orientation =
Quaternion::rotation_x(wave * 0.8) * Quaternion::rotation_z(wavealt / 6.0);
next.feet_f.scale = Vec3::one(); next.feet_f.scale = Vec3::one();
next.feet_b.position = Vec3::new(0.0, skeleton_attr.feet_b.0, skeleton_attr.feet_b.1); next.feet_b.position = Vec3::new(0.0, skeleton_attr.feet_b.0, skeleton_attr.feet_b.1);
next.feet_b.orientation = Quaternion::rotation_x(wave_cos * 1.0); next.feet_b.orientation =
Quaternion::rotation_x(wavealt * 0.8) * Quaternion::rotation_z(wavealt / 6.0);
next.feet_b.scale = Vec3::one(); next.feet_b.scale = Vec3::one();
next.tail.position = next.tail.position =

View File

@ -88,7 +88,7 @@ use crate::audio::AudioFrontend;
use common::{ use common::{
assets, assets,
comp::{ comp::{
item::{Consumable, ItemKind, ToolCategory}, item::{ItemKind, ToolCategory},
CharacterAbilityType, InventoryUpdateEvent, Ori, Pos, CharacterAbilityType, InventoryUpdateEvent, Ori, Pos,
}, },
event::EventBus, event::EventBus,
@ -153,7 +153,7 @@ pub enum SfxInventoryEvent {
Collected, Collected,
CollectedTool(ToolCategory), CollectedTool(ToolCategory),
CollectFailed, CollectFailed,
Consumed(Consumable), Consumed(String),
Debug, Debug,
Dropped, Dropped,
Given, Given,
@ -177,7 +177,7 @@ impl From<&InventoryUpdateEvent> for SfxEvent {
SfxEvent::Inventory(SfxInventoryEvent::CollectFailed) SfxEvent::Inventory(SfxInventoryEvent::CollectFailed)
}, },
InventoryUpdateEvent::Consumed(consumable) => { InventoryUpdateEvent::Consumed(consumable) => {
SfxEvent::Inventory(SfxInventoryEvent::Consumed(*consumable)) SfxEvent::Inventory(SfxInventoryEvent::Consumed(consumable.clone()))
}, },
InventoryUpdateEvent::Debug => SfxEvent::Inventory(SfxInventoryEvent::Debug), InventoryUpdateEvent::Debug => SfxEvent::Inventory(SfxInventoryEvent::Debug),
InventoryUpdateEvent::Dropped => SfxEvent::Inventory(SfxInventoryEvent::Dropped), InventoryUpdateEvent::Dropped => SfxEvent::Inventory(SfxInventoryEvent::Dropped),

View File

@ -77,8 +77,8 @@ impl State {
.filter(|kind| { .filter(|kind| {
use common::comp::item::{tool::ToolKind, ItemKind}; use common::comp::item::{tool::ToolKind, ItemKind};
if let ItemKind::Tool(kind) = kind { if let ItemKind::Tool(kind) = kind {
if let ToolKind::Staff(_) = &kind.kind { if let ToolKind::Staff(kind) = &kind.kind {
true kind != "Sceptre"
} else if let ToolKind::Debug(kind) = &kind.kind { } else if let ToolKind::Debug(kind) = &kind.kind {
kind == "Boost" kind == "Boost"
} else { } else {

View File

@ -4,7 +4,7 @@ use common::{
comp::item::{ comp::item::{
armor::{Armor, ArmorKind}, armor::{Armor, ArmorKind},
tool::{Tool, ToolKind}, tool::{Tool, ToolKind},
Consumable, Ingredient, Item, ItemKind, Lantern, LanternKind, Throwable, Utility, Item, ItemKind, Lantern, Throwable, Utility,
}, },
figure::Segment, figure::Segment,
}; };
@ -20,24 +20,24 @@ use vek::*;
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ItemKey { pub enum ItemKey {
Tool(ToolKind), Tool(ToolKind),
Lantern(LanternKind), Lantern(String),
Armor(ArmorKind), Armor(ArmorKind),
Utility(Utility), Utility(Utility),
Consumable(Consumable), Consumable(String),
Throwable(Throwable), Throwable(Throwable),
Ingredient(Ingredient), Ingredient(String),
Empty, Empty,
} }
impl From<&Item> for ItemKey { impl From<&Item> for ItemKey {
fn from(item: &Item) -> Self { fn from(item: &Item) -> Self {
match &item.kind { match &item.kind {
ItemKind::Tool(Tool { kind, .. }) => ItemKey::Tool(kind.clone()), ItemKind::Tool(Tool { kind, .. }) => ItemKey::Tool(kind.clone()),
ItemKind::Lantern(Lantern { kind, .. }) => ItemKey::Lantern(*kind), ItemKind::Lantern(Lantern { kind, .. }) => ItemKey::Lantern(kind.clone()),
ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()), ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()),
ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind), ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind),
ItemKind::Consumable { kind, .. } => ItemKey::Consumable(*kind), ItemKind::Consumable { kind, .. } => ItemKey::Consumable(kind.clone()),
ItemKind::Throwable { kind, .. } => ItemKey::Throwable(*kind), ItemKind::Throwable { kind, .. } => ItemKey::Throwable(*kind),
ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(*kind), ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(kind.clone()),
} }
} }
} }

View File

@ -8,7 +8,7 @@ use anim::Skeleton;
use common::{ use common::{
assets::watch::ReloadIndicator, assets::watch::ReloadIndicator,
comp::{ comp::{
item::{armor::ArmorKind, tool::ToolKind, ItemKind, LanternKind}, item::{armor::ArmorKind, tool::ToolKind, ItemKind},
Body, CharacterState, Loadout, Body, CharacterState, Loadout,
}, },
figure::Segment, figure::Segment,
@ -39,7 +39,7 @@ struct CharacterCacheKey {
chest: Option<ArmorKind>, chest: Option<ArmorKind>,
belt: Option<ArmorKind>, belt: Option<ArmorKind>,
back: Option<ArmorKind>, back: Option<ArmorKind>,
lantern: Option<LanternKind>, lantern: Option<String>,
hand: Option<ArmorKind>, hand: Option<ArmorKind>,
pants: Option<ArmorKind>, pants: Option<ArmorKind>,
foot: Option<ArmorKind>, foot: Option<ArmorKind>,
@ -88,7 +88,7 @@ impl CharacterCacheKey {
lantern: if let Some(ItemKind::Lantern(lantern)) = lantern: if let Some(ItemKind::Lantern(lantern)) =
loadout.lantern.as_ref().map(|i| &i.kind) loadout.lantern.as_ref().map(|i| &i.kind)
{ {
Some(lantern.kind) Some(lantern.kind.clone())
} else { } else {
None None
}, },

View File

@ -13,7 +13,7 @@ use common::{
item::{ item::{
armor::{Armor, ArmorKind}, armor::{Armor, ArmorKind},
tool::{Tool, ToolKind}, tool::{Tool, ToolKind},
ItemKind, Lantern, LanternKind, ItemKind, Lantern,
}, },
object, object,
quadruped_low::{BodyType as QLBodyType, Species as QLSpecies}, quadruped_low::{BodyType as QLBodyType, Species as QLSpecies},
@ -268,7 +268,7 @@ pub struct HumArmorFootSpec(ArmorVoxSpecMap<String, ArmorVoxSpec>);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct HumMainWeaponSpec(HashMap<ToolKind, ArmorVoxSpec>); pub struct HumMainWeaponSpec(HashMap<ToolKind, ArmorVoxSpec>);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct HumArmorLanternSpec(ArmorVoxSpecMap<LanternKind, ArmorVoxSpec>); pub struct HumArmorLanternSpec(ArmorVoxSpecMap<String, ArmorVoxSpec>);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct HumArmorHeadSpec(ArmorVoxSpecMap<String, ArmorVoxSpec>); pub struct HumArmorHeadSpec(ArmorVoxSpecMap<String, ArmorVoxSpec>);
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@ -841,7 +841,7 @@ impl HumArmorLanternSpec {
let spec = if let Some(ItemKind::Lantern(Lantern { kind, .. })) = let spec = if let Some(ItemKind::Lantern(Lantern { kind, .. })) =
loadout.lantern.as_ref().map(|i| &i.kind) loadout.lantern.as_ref().map(|i| &i.kind)
{ {
match self.0.map.get(&kind) { match self.0.map.get(kind) {
Some(spec) => spec, Some(spec) => spec,
None => { None => {
error!(?kind, "No lantern specification exists"); error!(?kind, "No lantern specification exists");