diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 85c3a65b59..9596928403 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ stages: - check + - build-nightly - build - publish - analyze diff --git a/.gitlab/CI/build.gitlab-ci.yml b/.gitlab/CI/build.gitlab-ci.yml index fbfc959f40..2fd5891474 100644 --- a/.gitlab/CI/build.gitlab-ci.yml +++ b/.gitlab/CI/build.gitlab-ci.yml @@ -74,6 +74,22 @@ macos: - .tmacos - .release +# build on schedule quickfix till airshipper 0.5 +air-linux: + extends: + - .tlinux + - .release-nightly-tmp-fix-airshipper + +air-windows: + extends: + - .twindows + - .release-nightly-tmp-fix-airshipper + +air-macos: + extends: + - .tmacos + - .release-nightly-tmp-fix-airshipper + # if NOT release or master, allow optional builds opt-linux: extends: diff --git a/.gitlab/CI/publish.gitlab-ci.yml b/.gitlab/CI/publish.gitlab-ci.yml index ee9a82a86f..407722f225 100644 --- a/.gitlab/CI/publish.gitlab-ci.yml +++ b/.gitlab/CI/publish.gitlab-ci.yml @@ -5,7 +5,16 @@ tags: - veloren-docker rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "schedule" + when: always + - when: never + +.publish-nightly: + stage: publish + tags: + - veloren-docker + rules: + - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: always - when: never @@ -20,7 +29,20 @@ docker: - ls "$CI_PROJECT_DIR/server-cli/" script: - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/server-cli/Dockerfile --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}-server" + - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/server-cli/Dockerfile --destination "${CI_REGISTRY_IMAGE}/server-cli:${CI_COMMIT_REF_NAME}" + +docker-nightly: + extends: .publish-nightly + image: + name: gcr.io/kaniko-project/executor:debug + entrypoint: [""] + dependencies: + - linux + before_script: + - ls "$CI_PROJECT_DIR/server-cli/" + script: + - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json + - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/server-cli/Dockerfile --destination "${CI_REGISTRY_IMAGE}/server-cli:nightly" pages: extends: .publish @@ -31,4 +53,4 @@ pages: - rm -rf public - mkdir -p public - cargo doc --no-deps --document-private-items - - mv target/doc/* public + - mv target/doc/* public \ No newline at end of file diff --git a/.gitlab/CI/release.yml b/.gitlab/CI/release.yml index 3de8a59b94..b87f56c9d8 100644 --- a/.gitlab/CI/release.yml +++ b/.gitlab/CI/release.yml @@ -9,12 +9,22 @@ - when: manual allow_failure: true -# Template to only run if pushes to master or a tag happened and it being triggered by a schedule +# Template to only run if pushes to master or a tag happened .release: stage: build tags: - veloren-docker rules: - - if: $CI_PIPELINE_SOURCE == "schedule" && ( $CI_COMMIT_REF_NAME =~ /^master$/ || $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+/ || $CI_COMMIT_REF_NAME =~ /^r[0-9]+\.[0-9]+/ ) + - if: $CI_COMMIT_REF_NAME =~ /^master$/ || $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+/ || $CI_COMMIT_REF_NAME =~ /^r[0-9]+\.[0-9]+/ when: always - when: never + +# Template to only run if pushes to master or a tag happened +.release-nightly-tmp-fix-airshipper: + stage: build-nightly + tags: + - veloren-docker + rules: + - if: $CI_PIPELINE_SOURCE == "schedule" && ($CI_COMMIT_REF_NAME =~ /^master$/ || $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+/ || $CI_COMMIT_REF_NAME =~ /^r[0-9]+\.[0-9]+/) + when: always + - when: never \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e43717338f..b0aa14db29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Entities now have density - Buoyancy is calculated from the difference in density between an entity and surrounding fluid - Drag is now calculated based on physical properties +- Terrain chunks are now deflate-compressed when sent over the network. +- Missing translations can be displayed in English. +- New large birds npcs +- Day period dependant wildlife spawns ### Changed @@ -74,6 +78,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Jump has been decreased in height but extended in length as a result of the new gravity - Fall damage has been adjusted with the new gravity in mind - Projectiles now generally have a different arc because they no longer have their own gravity modifier +- Increased agent system target search efficiency speeding up the server +- Added more parallelization to terrain serialization and removed extra cloning speeding up the server ### Removed @@ -92,6 +98,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Minimap icons are now displayed in both map modes - Server now denies any running trades when a user exits to the character selection screen. - Sfx volume changes now also change the ambient sounds volume +- Staff fire shockwave ability no longer has an unlimited vertical range +- Skillbar buttons correctly account for skill points when checking if player has enough stamina for the ability. ## [0.9.0] - 2021-03-20 diff --git a/Cargo.lock b/Cargo.lock index b27aa7160e..c36ba62d0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1308,6 +1308,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "deflate" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f95bf05dffba6e6cce8dfbb30def788154949ccd9aed761b472119c21e01c70" +dependencies = [ + "adler32", +] + [[package]] name = "derivative" version = "2.2.0" @@ -3765,7 +3774,7 @@ checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" dependencies = [ "bitflags", "crc32fast", - "deflate", + "deflate 0.8.6", "miniz_oxide 0.3.7", ] @@ -5443,7 +5452,7 @@ dependencies = [ "veloren-common-frontend", "veloren-common-net", "veloren-common-state", - "veloren-common-sys", + "veloren-common-systems", "veloren-network", ] @@ -5524,6 +5533,8 @@ dependencies = [ name = "veloren-common-net" version = "0.9.0" dependencies = [ + "bincode", + "flate2", "hashbrown", "serde", "specs", @@ -5557,7 +5568,7 @@ dependencies = [ ] [[package]] -name = "veloren-common-sys" +name = "veloren-common-systems" version = "0.9.0" dependencies = [ "hashbrown", @@ -5682,7 +5693,7 @@ dependencies = [ "veloren-common-ecs", "veloren-common-net", "veloren-common-state", - "veloren-common-sys", + "veloren-common-systems", "veloren-network", "veloren-plugin-api", "veloren-world", @@ -5770,7 +5781,7 @@ dependencies = [ "veloren-common-frontend", "veloren-common-net", "veloren-common-state", - "veloren-common-sys", + "veloren-common-systems", "veloren-server", "veloren-voxygen-anim", "veloren-world", @@ -5809,12 +5820,15 @@ dependencies = [ "bincode", "bitvec", "criterion", + "deflate 0.9.1", "enum-iterator", + "flate2", "fxhash", "hashbrown", "image", "itertools 0.10.0", "lazy_static", + "lz-fear", "minifb", "noise", "num 0.4.0", @@ -5831,6 +5845,7 @@ dependencies = [ "tracing-subscriber", "vek", "veloren-common", + "veloren-common-frontend", "veloren-common-net", ] diff --git a/Cargo.toml b/Cargo.toml index 2eb30662d7..d1cfa92648 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = [ "common/ecs", "common/net", "common/state", - "common/sys", + "common/systems", "common/frontend", "client", "plugin/api", diff --git a/assets/common/abilities/unique/birdlargebreathe/firebomb.ron b/assets/common/abilities/unique/birdlargebreathe/firebomb.ron new file mode 100644 index 0000000000..def79061ea --- /dev/null +++ b/assets/common/abilities/unique/birdlargebreathe/firebomb.ron @@ -0,0 +1,17 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.5, + recover_duration: 0.35, + projectile: Fireball( + damage: 100.0, + radius: 5.0, + energy_regen: 50, + ), + projectile_body: Object(BoltFire), + /*projectile_light: Some(LightEmitter { + col: (1.0, 0.75, 0.11).into(), + ..Default::default() + }),*/ + projectile_gravity: Some(Gravity(0.15)), + projectile_speed: 60.0, +) diff --git a/assets/common/abilities/unique/birdlargebreathe/flamethrower.ron b/assets/common/abilities/unique/birdlargebreathe/flamethrower.ron new file mode 100644 index 0000000000..4bf507fa86 --- /dev/null +++ b/assets/common/abilities/unique/birdlargebreathe/flamethrower.ron @@ -0,0 +1,14 @@ +BasicBeam( + buildup_duration: 0.4, + recover_duration: 0.25, + beam_duration: 0.5, + damage: 50, + tick_rate: 3.0, + range: 15.0, + max_angle: 22.5, + damage_effect: None, + energy_regen: 0, + energy_drain: 0, + orientation_behavior: Normal, + specifier: Flamethrower, +) \ No newline at end of file diff --git a/assets/common/abilities/unique/birdlargebreathe/triplestrike.ron b/assets/common/abilities/unique/birdlargebreathe/triplestrike.ron new file mode 100644 index 0000000000..2eaa09c043 --- /dev/null +++ b/assets/common/abilities/unique/birdlargebreathe/triplestrike.ron @@ -0,0 +1,53 @@ +ComboMelee( + stage_data: [ + ( + stage: 1, + base_damage: 100, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 5.0, + range: 4.5, + angle: 30.0, + base_buildup_duration: 0.4, + base_swing_duration: 0.1, + base_recover_duration: 0.3, + forward_movement: 2.0, + ), + ( + stage: 2, + base_damage: 80, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 5.0, + range: 3.5, + angle: 30.0, + base_buildup_duration: 0.4, + base_swing_duration: 0.1, + base_recover_duration: 0.3, + forward_movement: 1.5, + ), + ( + stage: 3, + base_damage: 130, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 10.0, + range: 3.5, + angle: 30.0, + base_buildup_duration: 0.65, + base_swing_duration: 0.1, + base_recover_duration: 0.3, + forward_movement: 1.5, + ), + ], + initial_energy_gain: 0, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 0.0, + scales_from_combo: 0, + is_interruptible: false, +) diff --git a/assets/common/abilities/unique/birdlargefire/firebomb.ron b/assets/common/abilities/unique/birdlargefire/firebomb.ron new file mode 100644 index 0000000000..def79061ea --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/firebomb.ron @@ -0,0 +1,17 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.5, + recover_duration: 0.35, + projectile: Fireball( + damage: 100.0, + radius: 5.0, + energy_regen: 50, + ), + projectile_body: Object(BoltFire), + /*projectile_light: Some(LightEmitter { + col: (1.0, 0.75, 0.11).into(), + ..Default::default() + }),*/ + projectile_gravity: Some(Gravity(0.15)), + projectile_speed: 60.0, +) diff --git a/assets/common/abilities/unique/birdlargefire/fireshockwave.ron b/assets/common/abilities/unique/birdlargefire/fireshockwave.ron new file mode 100644 index 0000000000..e7e1f67a0f --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/fireshockwave.ron @@ -0,0 +1,15 @@ +Shockwave( + energy_cost: 600, + buildup_duration: 0.7, + swing_duration: 0.1, + recover_duration: 0.2, + damage: 200, + poise_damage: 0, + knockback: ( strength: 25.0, direction: Away), + shockwave_angle: 360.0, + shockwave_vertical_angle: 90.0, + shockwave_speed: 20.0, + shockwave_duration: 0.5, + requires_ground: false, + move_efficiency: 0.1, +) diff --git a/assets/common/abilities/unique/birdlargefire/flamethrower.ron b/assets/common/abilities/unique/birdlargefire/flamethrower.ron new file mode 100644 index 0000000000..4bf507fa86 --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/flamethrower.ron @@ -0,0 +1,14 @@ +BasicBeam( + buildup_duration: 0.4, + recover_duration: 0.25, + beam_duration: 0.5, + damage: 50, + tick_rate: 3.0, + range: 15.0, + max_angle: 22.5, + damage_effect: None, + energy_regen: 0, + energy_drain: 0, + orientation_behavior: Normal, + specifier: Flamethrower, +) \ No newline at end of file diff --git a/assets/common/abilities/unique/birdlargefire/triplestrike.ron b/assets/common/abilities/unique/birdlargefire/triplestrike.ron new file mode 100644 index 0000000000..2eaa09c043 --- /dev/null +++ b/assets/common/abilities/unique/birdlargefire/triplestrike.ron @@ -0,0 +1,53 @@ +ComboMelee( + stage_data: [ + ( + stage: 1, + base_damage: 100, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 5.0, + range: 4.5, + angle: 30.0, + base_buildup_duration: 0.4, + base_swing_duration: 0.1, + base_recover_duration: 0.3, + forward_movement: 2.0, + ), + ( + stage: 2, + base_damage: 80, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 5.0, + range: 3.5, + angle: 30.0, + base_buildup_duration: 0.4, + base_swing_duration: 0.1, + base_recover_duration: 0.3, + forward_movement: 1.5, + ), + ( + stage: 3, + base_damage: 130, + damage_increase: 0, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 10.0, + range: 3.5, + angle: 30.0, + base_buildup_duration: 0.65, + base_swing_duration: 0.1, + base_recover_duration: 0.3, + forward_movement: 1.5, + ), + ], + initial_energy_gain: 0, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 0.0, + scales_from_combo: 0, + is_interruptible: false, +) diff --git a/assets/common/abilities/unique/stonegolemfist/shockwave.ron b/assets/common/abilities/unique/stonegolemfist/shockwave.ron index 1099d9aaf0..6f9d397774 100644 --- a/assets/common/abilities/unique/stonegolemfist/shockwave.ron +++ b/assets/common/abilities/unique/stonegolemfist/shockwave.ron @@ -1,8 +1,8 @@ Shockwave( energy_cost: 0, - buildup_duration: 1.5, - swing_duration: 0.15, - recover_duration: 1.8, + buildup_duration: 0.6, + swing_duration: 0.12, + recover_duration: 1.2, damage: 500, poise_damage: 50, knockback: (strength: 40.0, direction: TowardsUp), diff --git a/assets/common/abilities/weapon_ability_manifest.ron b/assets/common/abilities/weapon_ability_manifest.ron index 21a39831a8..e36d47685c 100644 --- a/assets/common/abilities/weapon_ability_manifest.ron +++ b/assets/common/abilities/weapon_ability_manifest.ron @@ -207,6 +207,20 @@ (None, "common.abilities.unique.mindflayer.summonminions"), ], ), + Unique(BirdLargeBreathe): ( + primary: "common.abilities.unique.birdlargebreathe.firebomb", + secondary: "common.abilities.unique.birdlargebreathe.triplestrike", + abilities: [ + (None, "common.abilities.unique.birdlargebreathe.flamethrower"), + ], + ), + Unique(BirdLargeFire): ( + primary: "common.abilities.unique.birdlargefire.firebomb", + secondary: "common.abilities.unique.birdlargefire.triplestrike", + abilities: [ + (None, "common.abilities.unique.birdlargefire.fireshockwave"), + ], + ), Debug: ( primary: "common.abilities.debug.forwardboost", secondary: "common.abilities.debug.upboost", diff --git a/assets/common/items/boss_drops/lantern.ron b/assets/common/items/boss_drops/lantern.ron index eeb23cf6cc..82fa2c248d 100644 --- a/assets/common/items/boss_drops/lantern.ron +++ b/assets/common/items/boss_drops/lantern.ron @@ -3,12 +3,12 @@ ItemDef( description: "Illuminates even the darkest dungeon\nA great monster was slain for this item", kind: Lantern( ( - kind: "Blue0", + kind: "Green0", color: (r: 128, g: 26, b: 255), strength_thousandths: 8500, flicker_thousandths: 300, ), ), - quality: High, + quality: Epic, tags: [Utility], ) diff --git a/assets/common/items/npc_weapons/unique/birdlargebreathe.ron b/assets/common/items/npc_weapons/unique/birdlargebreathe.ron new file mode 100644 index 0000000000..15b41aa6ed --- /dev/null +++ b/assets/common/items/npc_weapons/unique/birdlargebreathe.ron @@ -0,0 +1,18 @@ +ItemDef( + name: "Bird Large Breathe", + description: "testing123", + kind: Tool(( + kind: Unique(BirdLargeBreathe), + hands: Two, + stats: Direct(( + equip_time_secs: 0.01, + power: 1.0, + poise_strength: 1.0, + speed: 1.0, + crit_chance: 0.0625, + crit_mult: 1.9142857, + )), + )), + quality: Low, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/unique/birdlargefire.ron b/assets/common/items/npc_weapons/unique/birdlargefire.ron new file mode 100644 index 0000000000..b092a15f0f --- /dev/null +++ b/assets/common/items/npc_weapons/unique/birdlargefire.ron @@ -0,0 +1,18 @@ +ItemDef( + name: "Bird Large Fire", + description: "testing123", + kind: Tool(( + kind: Unique(BirdLargeFire), + hands: Two, + stats: Direct(( + equip_time_secs: 0.01, + power: 1.0, + poise_strength: 1.0, + speed: 1.0, + crit_chance: 0.0625, + crit_mult: 1.9142857, + )), + )), + quality: Low, + tags: [], +) \ No newline at end of file diff --git a/assets/common/npc_names.ron b/assets/common/npc_names.ron index 5f273b5593..2729cacb40 100644 --- a/assets/common/npc_names.ron +++ b/assets/common/npc_names.ron @@ -804,10 +804,6 @@ keyword: "parrot", generic: "Parrot" ), - cockatrice: ( - keyword: "cockatrice", - generic: "Cockatrice" - ) ) ), biped_large: ( @@ -1068,12 +1064,23 @@ ) ) ), - bird_small: ( + bird_large: ( body: ( - keyword: "bird_small", - names_0: [] + keyword: "bird_large", + names_0: [ + "Aitvaras" + ] ), - species: () + species: ( + phoenix: ( + keyword: "phoenix", + generic: "Phoenix" + ), + cockatrice: ( + keyword: "cockatrice", + generic: "Cockatrice" + ), + ) ), quadruped_low: ( body: ( diff --git a/assets/voxygen/i18n/en/_manifest.ron b/assets/voxygen/i18n/en/_manifest.ron index 3efbe2d98c..737713c4dc 100644 --- a/assets/voxygen/i18n/en/_manifest.ron +++ b/assets/voxygen/i18n/en/_manifest.ron @@ -229,7 +229,7 @@ "npc.speech.villager_enemy_killed": [ "I have destroyed my enemy!", "Finally at peace!", - "... now what I was doing?", + "... now what was I doing?", ] } ) diff --git a/assets/voxygen/i18n/en/char_selection.ron b/assets/voxygen/i18n/en/char_selection.ron index a078c83a81..7f60914312 100644 --- a/assets/voxygen/i18n/en/char_selection.ron +++ b/assets/voxygen/i18n/en/char_selection.ron @@ -24,6 +24,7 @@ "char_selection.eyeshape": "Eye Details", "char_selection.accessories": "Accessories", "char_selection.create_info_name": "Your Character needs a name!", + "char_selection.version_mismatch": "WARNING! This server is running a different, possibly incompatible game version. Please update your game." }, vector_map: { diff --git a/assets/voxygen/i18n/en/hud/hud_settings.ron b/assets/voxygen/i18n/en/hud/hud_settings.ron index 7706b81b24..d7c5ffc949 100644 --- a/assets/voxygen/i18n/en/hud/hud_settings.ron +++ b/assets/voxygen/i18n/en/hud/hud_settings.ron @@ -101,6 +101,8 @@ "hud.settings.audio_device": "Audio Device", "hud.settings.reset_sound": "Reset to Defaults", + "hud.settings.english_fallback": "Display English for missing translations", + "hud.settings.awaitingkey": "Press a key...", "hud.settings.unbound": "None", "hud.settings.reset_keybinds": "Reset to Defaults", diff --git a/assets/voxygen/i18n/en/main.ron b/assets/voxygen/i18n/en/main.ron index ab22a8ac9d..6bf3f4da12 100644 --- a/assets/voxygen/i18n/en/main.ron +++ b/assets/voxygen/i18n/en/main.ron @@ -50,7 +50,7 @@ https://veloren.net/account/."#, "main.login.timeout": "Timeout: Server did not respond in time. (Overloaded or network issues).", "main.login.server_shut_down": "Server shut down", "main.login.network_error": "Network error", - "main.login.network_wrong_version": "The server is running a different version than you are. Check your version and update your game.", + "main.login.network_wrong_version": "Mismatched server and client version, please update your game client.", "main.login.failed_sending_request": "Request to Auth server failed", "main.login.invalid_character": "The selected character is invalid", "main.login.client_crashed": "Client crashed", @@ -58,7 +58,8 @@ https://veloren.net/account/."#, "main.login.banned": "You have been banned with the following reason", "main.login.kicked": "You have been kicked with the following reason", "main.login.select_language": "Select a language", - + "main.login.client_version": "Client Version", + "main.login.server_version": "Server Version", "main.servers.select_server": "Select a server", /// End Main screen section }, diff --git a/assets/voxygen/i18n/pt_BR/gameinput.ron b/assets/voxygen/i18n/pt_BR/gameinput.ron index 3942b915cd..34d62a49c7 100644 --- a/assets/voxygen/i18n/pt_BR/gameinput.ron +++ b/assets/voxygen/i18n/pt_BR/gameinput.ron @@ -62,6 +62,8 @@ "gameinput.sneak": "Furtividade", "gameinput.swimdown": "Mergulhar", "gameinput.swimup": "Emergir", + "gameinput.mapzoomin": "Aumentar zoom do mapa", + "gameinput.mapzoomout": "Reduzir zoom do mapa", }, diff --git a/assets/voxygen/i18n/pt_BR/hud/bag.ron b/assets/voxygen/i18n/pt_BR/hud/bag.ron index 5bb81f1b35..db40304433 100644 --- a/assets/voxygen/i18n/pt_BR/hud/bag.ron +++ b/assets/voxygen/i18n/pt_BR/hud/bag.ron @@ -33,6 +33,9 @@ "hud.bag.combat_rating_desc": "Calculado por seu\nequipamento e vida.", "hud.bag.protection_desc": "Redução de dano por armadura", "hud.bag.stun_res_desc": "Resistência à paralisia provocada por golpes consecutivos.\nRegenera como Stamina.", + "hud.bag.sort_by_name": "Ordenar por Nome", + "hud.bag.sort_by_quality": "Ordenar por Qualidade", + "hud.bag.sort_by_category": "Ordenar por Categoria", }, diff --git a/assets/voxygen/i18n/pt_BR/hud/crafting.ron b/assets/voxygen/i18n/pt_BR/hud/crafting.ron index 456684434d..152431988e 100644 --- a/assets/voxygen/i18n/pt_BR/hud/crafting.ron +++ b/assets/voxygen/i18n/pt_BR/hud/crafting.ron @@ -8,7 +8,12 @@ "hud.crafting.ingredients": "Ingredientes:", "hud.crafting.craft": "Criar", "hud.crafting.tool_cata": "Requer:", - + // Crafting Stations (Estações de Criação) + "hud.crafting.req_crafting_station": "Requer:", + "hud.crafting.anvil": "Bigorna", + "hud.crafting.cauldron": "Caldeirão", + "hud.crafting.cooking_pot": "Panela", + "hud.crafting.crafting_bench": "Bancada de Criação", // Tabs (Abas) "hud.crafting.tabs.all": "Tudo", "hud.crafting.tabs.armor": "Armadura", diff --git a/assets/voxygen/i18n/pt_BR/hud/hud_settings.ron b/assets/voxygen/i18n/pt_BR/hud/hud_settings.ron index b7b5db4316..549f7c105f 100644 --- a/assets/voxygen/i18n/pt_BR/hud/hud_settings.ron +++ b/assets/voxygen/i18n/pt_BR/hud/hud_settings.ron @@ -36,7 +36,7 @@ "hud.settings.background_transparency": "Transparência de Fundo", "hud.settings.chat_character_name": "Nomes de Personagem no chat", "hud.settings.loading_tips": "Dicas na Tela de Carregamento", - "hud.settings.reset_interface": "Voltar para o padrão", + "hud.settings.reset_interface": "Restaurar Padrões", "hud.settings.pan_sensitivity": "Sensibilidade de Rotação", "hud.settings.zoom_sensitivity": "Sensibilidade do Zoom", @@ -51,7 +51,7 @@ "hud.settings.player_physics_behavior": "Física do Jogador (experimental)", "hud.settings.stop_auto_walk_on_input": "Parar caminhar automático em caso de movimento", "hud.settings.auto_camera": "Câmera automática", - "hud.settings.reset_gameplay": "Voltar para o padrão", + "hud.settings.reset_gameplay": "Restaurar Padrões", "hud.settings.view_distance": "Alcance de Visão", "hud.settings.sprites_view_distance": "Distância de visão dos Sprites", @@ -91,17 +91,19 @@ "hud.settings.shadow_rendering_mode.map.resolution": "Resolução", "hud.settings.lod_detail": "Detalhes", "hud.settings.save_window_size": "Salvar Dimensões da Janela", - "hud.settings.reset_graphics": "Voltar para o padrão", + "hud.settings.reset_graphics": "Restaurar Padrões", + "hud.settings.master_volume": "Volume Principal", + "hud.settings.inactive_master_volume": "Volume Principal (janela inativa)", "hud.settings.music_volume": "Volume da Música", "hud.settings.sound_effect_volume": "Volume dos Efeitos", "hud.settings.audio_device": "Dispositivo de Áudio", - "hud.settings.reset_sound": "Voltar para o padrão", + "hud.settings.reset_sound": "Restaurar Padrões", "hud.settings.awaitingkey": "Pressione uma tecla...", "hud.settings.unbound": "Nenhum", - "hud.settings.reset_keybinds": "Voltar para o padrão", + "hud.settings.reset_keybinds": "Restaurar Padrões", }, diff --git a/assets/voxygen/i18n/pt_BR/skills.ron b/assets/voxygen/i18n/pt_BR/skills.ron index 6f6219e2ef..dc9958ec0d 100644 --- a/assets/voxygen/i18n/pt_BR/skills.ron +++ b/assets/voxygen/i18n/pt_BR/skills.ron @@ -101,8 +101,6 @@ "hud.skill.st_fireball" : "Brinque de perseguir seus inimigos", "hud.skill.st_damage_title" : "Dano", "hud.skill.st_damage" : "Aumenta o dano em 20%{SP}", - "hud.skill.st_explosion_title" : "Explosão", - "hud.skill.st_explosion" : "Quando apenas fogo não é o bastante{SP}", // Arco "hud.skill.bow_projectile_speed_title" : "Velocidade do Projétil", "hud.skill.bow_projectile_speed" : "Permite atirar mais flechas, com velocidade aumentada em 30%{SP}", @@ -191,8 +189,8 @@ "hud.skill.sw_dash_cost": "Reduz custo inicial da investida em 25%{SP}", "hud.skill.sw_dash_speed_title": "Velocidade de Investida", "hud.skill.sw_dash_speed": "Aumenta a velocidade durante a investida em 15%{SP}", - "hud.skill.sw_dash_inf_title": "Investida do Infinito", - "hud.skill.sw_dash_inf": "Você consegue investir contanto que possua energia para tal{SP}", + "hud.skill.sw_dash_charge_through_title": "Intestida Trespassada", + "hud.skill.sw_dash_charge_through": "Permite que você atravésse os primeiros inimigos que você atinge{SP}", "hud.skill.sw_dash_scale_title": "Investida Acumulada", "hud.skill.sw_dash_scale": "Aumenta o acumulo de dano da investida em 20%{SP}", "hud.skill.sw_spin_title": "Liberar Rodopio", diff --git a/assets/voxygen/i18n/uk_UA/_manifest.ron b/assets/voxygen/i18n/uk_UA/_manifest.ron index dbfd4d1e9e..6db06f78b0 100644 --- a/assets/voxygen/i18n/uk_UA/_manifest.ron +++ b/assets/voxygen/i18n/uk_UA/_manifest.ron @@ -180,11 +180,11 @@ "npc.speech.merchant_trade_successful": [ "Було приємно мати з вами справу!", "Заходьте ще!", - "Дякую!", + "Дякую що обрали нас!", ], "npc.speech.merchant_trade_declined": [ "Не підійшло? Можливо в інший раз!", - "Доброго дня, до побачення!", + "Все одно, на все добре!", ], "npc.speech.villager_cultist_alarm": [ "Увага! Культист крадеться!", diff --git a/assets/voxygen/i18n/uk_UA/common.ron b/assets/voxygen/i18n/uk_UA/common.ron index 645126c8b0..c7f7f8d626 100644 --- a/assets/voxygen/i18n/uk_UA/common.ron +++ b/assets/voxygen/i18n/uk_UA/common.ron @@ -67,7 +67,7 @@ "common.weapons.staff": "Посох", "common.weapons.bow": "Лук", "common.weapons.hammer": "Молот", - "common.weapons.sceptre": "Цілющий Скіпетр", + "common.weapons.sceptre": "Скіпетр", "common.weapons.shield": "Щит", "common.weapons.spear": "Спис", "common.weapons.general": "Бій (загальне)", diff --git a/assets/voxygen/i18n/uk_UA/gameinput.ron b/assets/voxygen/i18n/uk_UA/gameinput.ron index afc8e9ea20..2038fb0723 100644 --- a/assets/voxygen/i18n/uk_UA/gameinput.ron +++ b/assets/voxygen/i18n/uk_UA/gameinput.ron @@ -4,7 +4,7 @@ ( string_map: { "gameinput.primary": "Базова атака", - "gameinput.secondary": "Другорядна атака/Блок/Приціл", + "gameinput.secondary": "Додаткова атака", "gameinput.slot1": "Слот швидкого доступу 1", "gameinput.slot2": "Слот швидкого доступу 2", "gameinput.slot3": "Слот швидкого доступу 3", @@ -40,6 +40,7 @@ "gameinput.escape": "Вихід", "gameinput.map": "Мапа", "gameinput.bag": "Інвентар", + "gameinput.trade": "Торгувати", "gameinput.social": "Інші гравці", "gameinput.sit": "Сісти", "gameinput.spellbook": "Чари", @@ -49,7 +50,7 @@ "gameinput.togglewield": "Дістати зброю", "gameinput.interact": "Взаємодіяти", "gameinput.freelook": "Вільний огляд", - "gameinput.autowalk": "Авто-хода", + "gameinput.autowalk": "Авто Рух/Політ", "gameinput.dance": "Танцювати", "gameinput.select": "Обрати", "gameinput.acceptgroupinvite": "Прийняти запрошення в групу", @@ -61,7 +62,8 @@ "gameinput.swimup": "Випливати", "gameinput.cameraclamp": "Закріпити камеру", "gameinput.cyclecamera": "Крутити камеру", - "gameinput.trade": "Торгувати", + "gameinput.mapzoomin": "Приблизити мапу", + "gameinput.mapzoomout": "Віддалити мапу", }, diff --git a/assets/voxygen/i18n/uk_UA/hud/crafting.ron b/assets/voxygen/i18n/uk_UA/hud/crafting.ron index 1392fbaf53..0fe287ea94 100644 --- a/assets/voxygen/i18n/uk_UA/hud/crafting.ron +++ b/assets/voxygen/i18n/uk_UA/hud/crafting.ron @@ -9,6 +9,13 @@ "hud.crafting.craft": "Виготовити", "hud.crafting.tool_cata": "Необхідно:", + // Crafting Stations + "hud.crafting.req_crafting_station": "Необхідне Приладдя:", + "hud.crafting.anvil": "Ковадло", + "hud.crafting.cauldron": "Казан", + "hud.crafting.cooking_pot": "Кастрюля", + "hud.crafting.crafting_bench": "Верстак", + // Tabs "hud.crafting.tabs.all": "Усе", "hud.crafting.tabs.armor": "Броня", diff --git a/assets/voxygen/i18n/uk_UA/hud/hud_settings.ron b/assets/voxygen/i18n/uk_UA/hud/hud_settings.ron index bb600dcb4a..e452ebd24c 100644 --- a/assets/voxygen/i18n/uk_UA/hud/hud_settings.ron +++ b/assets/voxygen/i18n/uk_UA/hud/hud_settings.ron @@ -18,14 +18,14 @@ "hud.settings.transparency": "Прозорість", "hud.settings.hotbar": "Панель швидкого доступу", "hud.settings.toggle_shortcuts": "Гарячі клавіші", - "hud.settings.buffs_skillbar": "Бафи на панелі навичок", - "hud.settings.buffs_mmap": "Бафи на мінімапі", + "hud.settings.buffs_skillbar": "Бафи біля Панелі Швидкого Доступу", + "hud.settings.buffs_mmap": "Бафи біля Мінімапи", "hud.settings.toggle_bar_experience": "Панель досвіду", - "hud.settings.scrolling_combat_text": "Текст під час бою", - "hud.settings.single_damage_number": "Заподіяні ушкодження (одиничні)", - "hud.settings.cumulated_damage": "Заподіяні ушкодження (кумулятивні)", - "hud.settings.incoming_damage": "Отримані ушкодження (одиничні)", - "hud.settings.cumulated_incoming_damage": "Отримані ушкодження (кумулятивні)", + "hud.settings.scrolling_combat_text": "Відображення Пошкоджень/Зцілень", + "hud.settings.single_damage_number": "Роздільно нанесені Гравцем", + "hud.settings.cumulated_damage": "Сумарно нанесені Гравцем", + "hud.settings.incoming_damage": "Роздільно отримані Гравцем", + "hud.settings.cumulated_incoming_damage": "Сумарно отримані Гравцем", "hud.settings.speech_bubble": "Діалоги", "hud.settings.speech_bubble_dark_mode": "Темний режим", "hud.settings.speech_bubble_icon": "Піктограма", @@ -60,11 +60,11 @@ "hud.settings.gamma": "Гамма", "hud.settings.exposure": "Експозиція", "hud.settings.ambiance": "Заповнююча яскравість", - "hud.settings.antialiasing_mode": "Режим анти-аліасингу", - "hud.settings.upscale_factor": "Коефіцієнт збільшення", - "hud.settings.cloud_rendering_mode": "Режим відображення хмар", - "hud.settings.fluid_rendering_mode": "Режим відображення рідин", - "hud.settings.fluid_rendering_mode.cheap": "Простий", + "hud.settings.antialiasing_mode": "Режим Анти-Аліасингу", + "hud.settings.upscale_factor": "Внутрішня Роздільна Здатність", + "hud.settings.cloud_rendering_mode": "Режим відображення Хмар", + "hud.settings.fluid_rendering_mode": "Режим відображення Рідин", + "hud.settings.fluid_rendering_mode.cheap": "Дешевий", "hud.settings.fluid_rendering_mode.shiny": "Блискучий", "hud.settings.cloud_rendering_mode.minimal": "Мінімальний", "hud.settings.cloud_rendering_mode.low": "Низький", @@ -76,23 +76,25 @@ "hud.settings.fullscreen_mode.exclusive": "Ексклюзивний", "hud.settings.fullscreen_mode.borderless": "Вікно без рамок", "hud.settings.particles": "Частинки", - "hud.settings.resolution": "Розширення", + "hud.settings.resolution": "Роздільна здатність", "hud.settings.bit_depth": "Глибина кольору", "hud.settings.refresh_rate": "Частота оновлення", - "hud.settings.lighting_rendering_mode": "Режим освітлення", + "hud.settings.lighting_rendering_mode": "Режим Освітлення", "hud.settings.lighting_rendering_mode.ashikhmin": "Тип A - Високий", "hud.settings.lighting_rendering_mode.blinnphong": "Тип B - Середній", - "hud.settings.lighting_rendering_mode.lambertian": "Тип L - Простий", - "hud.settings.shadow_rendering_mode": "Режим відображення тіней", + "hud.settings.lighting_rendering_mode.lambertian": "Тип L - Дешевий", + "hud.settings.shadow_rendering_mode": "Режим відображення Тіней", "hud.settings.shadow_rendering_mode.none": "Без тіней", - "hud.settings.shadow_rendering_mode.cheap": "Простий", + "hud.settings.shadow_rendering_mode.cheap": "Дешевий", "hud.settings.shadow_rendering_mode.map": "Карта тіней", "hud.settings.shadow_rendering_mode.map.resolution": "Роздільна здатність", "hud.settings.lod_detail": "Рівень деталізації", "hud.settings.save_window_size": "Зберегти розмір вікна", - "hud.settings.music_volume": "Гучність музики", - "hud.settings.sound_effect_volume": "Гучність звукових ефектів", + "hud.settings.master_volume": "Гучність", + "hud.settings.inactive_master_volume": "Гучність (якщо вікно неактивне)", + "hud.settings.music_volume": "Гучність Музики", + "hud.settings.sound_effect_volume": "Гучність Звукових Eфектів", "hud.settings.audio_device": "Звуковий пристрій", "hud.settings.awaitingkey": "Натисніть клавішу...", diff --git a/assets/voxygen/i18n/uk_UA/hud/misc.ron b/assets/voxygen/i18n/uk_UA/hud/misc.ron index cf438ae1ad..367b6aabc0 100644 --- a/assets/voxygen/i18n/uk_UA/hud/misc.ron +++ b/assets/voxygen/i18n/uk_UA/hud/misc.ron @@ -42,7 +42,7 @@ "hud.diary": "Щоденник", "hud.free_look_indicator": "Вільний огляд активовано. Натисніть {key}, щоб вимкнути.", - "hud.auto_walk_indicator": "Авто-хода активована", + "hud.auto_walk_indicator": "Авто Рух/Політ активовано", "hud.camera_clamp_indicator": "Камера вертикально закріплена. Натисніть {key} щоб відімкнути", }, diff --git a/assets/voxygen/i18n/uk_UA/skills.ron b/assets/voxygen/i18n/uk_UA/skills.ron index 82992cd70e..2802f243c3 100644 --- a/assets/voxygen/i18n/uk_UA/skills.ron +++ b/assets/voxygen/i18n/uk_UA/skills.ron @@ -25,8 +25,8 @@ "hud.skill.unlck_staff": "Відкриває дерево навичок володіння посохом{SP}", "hud.skill.unlck_sceptre_title": "Цілющий скіпетр", "hud.skill.unlck_sceptre": "Відкриває дерево навичок володіння цілющим скіпетром{SP}", - "hud.skill.dodge_title": "Перекид", - "hud.skill.dodge": "Перекид дозволяє ухилятись від ближніх атак{SP}", + "hud.skill.dodge_title": "Ухил", + "hud.skill.dodge": "Станьте невразливим до ближніх атак під час перекиду{SP}", "hud.skill.roll_stamina_title": "Енергоспоживання перекиду", "hud.skill.roll_stamina": "Перекид споживає на 10% менше енергії{SP}", "hud.skill.roll_speed_title": "Швидкість перекиду", @@ -96,7 +96,7 @@ "hud.skill.st_flamethrower_range" : "Збільшує дальність дії вогнемету 25%{SP}", "hud.skill.st_energy_drain_title" : "Енергоспоживання вогнемету", "hud.skill.st_energy_drain" : "Зменшує швидкість споживання енергії вогнеметом на 20%{SP}", - "hud.skill.st_fireball": "Не хотів би я бути воротарем", + "hud.skill.st_fireball": "Запускає вогняні кулі, що вибухають вражаючи ціль", "hud.skill.st_fireball_title": "Вогнений м'яч", "hud.skill.st_explosion_radius_title" : "Радіус вибуху", "hud.skill.st_explosion_radius" : "Більше - краще, збільшує радіус вибуху снарядів на 15%{SP}", @@ -194,8 +194,8 @@ "hud.skill.sw_dash_cost": "Зменшує початкову енергетичну ціну випаду на 25%{SP}", "hud.skill.sw_dash_speed_title": "Швидкість випаду", "hud.skill.sw_dash_speed": "Збільшує швидкість руху під час випаду 15%{SP}", - "hud.skill.sw_dash_inf_title": "Необмежений випад", - "hud.skill.sw_dash_inf": "Дозволяє нестись в випаді доки не закінчиться енергія{SP}", + "hud.skill.sw_dash_charge_through_title": "Ривок Наскрізь", + "hud.skill.sw_dash_charge_through": "Дозволяє прорватись наскрізь першого ворога{SP}", "hud.skill.sw_dash_scale_title": "Приріст ушкодження випадом", "hud.skill.sw_dash_scale": "Збільшує приріст ушкодження випадом на 20%{SP}", "hud.skill.sw_spin_title": "Кружляння", @@ -234,13 +234,13 @@ "hud.skill.axe_spin_speed_title": "Швидкість кружляння", "hud.skill.axe_spin_speed": "Збільшує швидкість кружляння на 25%{SP}", "hud.skill.axe_spin_cost_title": "Енергоспоживання кружляння", - "hud.skill.axe_spin_cost": "Зменшує споживання енергії в кружлянні на 25%", + "hud.skill.axe_spin_cost": "Зменшує споживання енергії в кружлянні на 25%{SP}", "hud.skill.axe_unlock_leap_title": "Атака в стрибку", "hud.skill.axe_unlock_leap": "Відкриває атаку в стрибку{SP}", "hud.skill.axe_leap_damage_title": "Ушкодження атакою в стрибку", "hud.skill.axe_leap_damage": "Збільшує ушкодження від атаки в стрибку на 35%{SP}", "hud.skill.axe_leap_knockback_title": "Відкидання атакою в стрибку", - "hud.skill.axe_leap_knockback": "Збільшує відстань відкидання від атаки в стрибку на 40%", + "hud.skill.axe_leap_knockback": "Збільшує відстань відкидання від атаки в стрибку на 40%{SP}", "hud.skill.axe_leap_cost_title": "Енергоспоживання атаки в стрибку", "hud.skill.axe_leap_cost": "Зменшує споживання енергії атакою в стрибку на 25%{SP}", "hud.skill.axe_leap_distance_title": "Дальність стрибка", diff --git a/assets/voxygen/shaders/include/light.glsl b/assets/voxygen/shaders/include/light.glsl index e30c1fc052..8c64bd037d 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -184,7 +184,8 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve #if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0 is_direct = true; #endif - vec3 direct_light = PI * color * strength * square_factor * light_reflection_factor(/*direct_norm_dir*/wnorm, /*cam_to_frag*/view_dir, direct_light_dir, k_d, k_s, alpha, voxel_norm, voxel_lighting); + vec3 lrf = light_reflection_factor(/*direct_norm_dir*/wnorm, /*cam_to_frag*/view_dir, direct_light_dir, k_d, k_s, alpha, voxel_norm, voxel_lighting); + vec3 direct_light = PI * color * strength * square_factor * pow(lrf, vec3(0.5)); // TODO: Don't use ^0.5, it's non-physical but helps with hill climbing float computed_shadow = ShadowCalculationPoint(i, -difference, wnorm, wpos/*, light_distance*/); // directed_light += is_direct ? max(computed_shadow, /*LIGHT_AMBIANCE*/0.0) * direct_light * square_factor : vec3(0.0); #ifdef FIGURE_SHADER diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index 1fe702656c..6d8d6b2695 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -107,7 +107,7 @@ void main() { // mat4 invfoo = foo * inverse(foo * all_mat); // vec3 old_coord = all_mat * vec4(f_pos.xyz, 1.0); // vec4 new_f_pos = invfoo * (old_coord);//vec4(f_pos, 1.0); - vec3 f_col_raw = mix(lod_col(f_pos.xy), vec3(0), clamp(pull_down / 10, 0, 1)); + vec3 f_col_raw = mix(lod_col(f_pos.xy), vec3(0), clamp(pull_down / 30, 0, 1)); // tgt_color = vec4(f_col, 1.0); // return; // vec3 f_col = srgb_to_linear(vec3(1.0)); diff --git a/assets/voxygen/shaders/lod-terrain-vert.glsl b/assets/voxygen/shaders/lod-terrain-vert.glsl index c482ad367b..5f03cf934c 100644 --- a/assets/voxygen/shaders/lod-terrain-vert.glsl +++ b/assets/voxygen/shaders/lod-terrain-vert.glsl @@ -49,7 +49,8 @@ void main() { // f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy)); - pull_down = 1.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0); + float dist = distance(focus_pos.xy, f_pos.xy); + pull_down = 0.2 / pow(dist / (view_distance.x * 0.9), 20.0); f_pos.z -= pull_down; // f_pos.z -= 100.0 * pow(1.0 + 0.01 / view_distance.x, -pow(distance(focus_pos.xy, f_pos.xy), 2.0)); @@ -98,6 +99,8 @@ void main() { view_mat * */ all_mat * vec4(f_pos/*newRay*/, 1); + // Pull up the depth to avoid drawing over voxels (biased according to VD) + gl_Position.z += 0.1 * clamp((view_distance.x * 1.0 - dist) * 0.01, 0, 1); // gl_Position.z = -gl_Position.z / gl_Position.w; // gl_Position.z = -gl_Position.z / gl_Position.w; // gl_Position.z = -gl_Position.z * gl_Position.w; diff --git a/assets/voxygen/voxel/armor/misc/lantern/black-0.vox b/assets/voxygen/voxel/armor/misc/lantern/black-0.vox deleted file mode 100644 index 620f002bf3..0000000000 --- a/assets/voxygen/voxel/armor/misc/lantern/black-0.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3057877edf5bd955d80fed44b00f64c0fae9287f4cb9cb417b3cdcefc899d424 -size 1384 diff --git a/assets/voxygen/voxel/armor/misc/lantern/blue-0.vox b/assets/voxygen/voxel/armor/misc/lantern/blue-0.vox deleted file mode 100644 index 8012f31a8f..0000000000 --- a/assets/voxygen/voxel/armor/misc/lantern/blue-0.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:54692b8a8fe500c7bb352033f06696123924fab78e3cf1e3a08ed610cef36de9 -size 1384 diff --git a/assets/voxygen/voxel/armor/misc/lantern/green-0.vox b/assets/voxygen/voxel/armor/misc/lantern/green-0.vox deleted file mode 100644 index 6305f11288..0000000000 --- a/assets/voxygen/voxel/armor/misc/lantern/green-0.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ee771034347313e31f4518019911b832deb71f074494225e9b771b485826257 -size 1384 diff --git a/assets/voxygen/voxel/armor/misc/lantern/red-0.vox b/assets/voxygen/voxel/armor/misc/lantern/red-0.vox deleted file mode 100644 index 2cfc2142e7..0000000000 --- a/assets/voxygen/voxel/armor/misc/lantern/red-0.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9d168ab7baea56575aa7542305691a932d80ba449079076ef166c2490cd53844 -size 1384 diff --git a/assets/voxygen/voxel/bird_large_central_manifest.ron b/assets/voxygen/voxel/bird_large_central_manifest.ron new file mode 100644 index 0000000000..f8a0999986 --- /dev/null +++ b/assets/voxygen/voxel/bird_large_central_manifest.ron @@ -0,0 +1,106 @@ +({ + (Phoenix, Male): ( + head: ( + offset: (-4.0, -4.0, 0.0), + central: ("npc.phoenix.male.head"), + ), + beak: ( + offset: (-2.0, 0.0, -3.0), + central: ("npc.phoenix.male.beak"), + ), + neck: ( + offset: (-4.0, 0.0, 0.0), + central: ("npc.phoenix.male.neck"), + ), + chest: ( + offset: (-6.0, -9.5, -7.5), + central: ("npc.phoenix.male.chest"), + ), + tail_front: ( + offset: (-10.0, -14.0, -3.0), + central: ("npc.phoenix.male.tail_front"), + ), + tail_rear: ( + offset: (-9.0, -30.0, -2.0), + central: ("npc.phoenix.male.tail_rear"), + ) + ), + (Phoenix, Female): ( + head: ( + offset: (-4.0, -4.0, 0.0), + central: ("npc.phoenix.male.head"), + ), + beak: ( + offset: (-2.0, 0.0, -3.0), + central: ("npc.phoenix.male.beak"), + ), + neck: ( + offset: (-4.0, 0.0, 0.0), + central: ("npc.phoenix.male.neck"), + ), + chest: ( + offset: (-6.0, -9.5, -7.5), + central: ("npc.phoenix.male.chest"), + ), + tail_front: ( + offset: (-10.0, -14.0, -3.0), + central: ("npc.phoenix.male.tail_front"), + ), + tail_rear: ( + offset: (-9.0, -30.0, -2.0), + central: ("npc.phoenix.male.tail_rear"), + ) + ), + (Cockatrice, Male): ( + head: ( + offset: (-4.5, -6.0, -3.5), + central: ("npc.cockatrice.male.head"), + ), + beak: ( + offset: (-1.5, 0.0, -1.5), + central: ("npc.cockatrice.male.beak"), + ), + neck: ( + offset: (-3.5, 0.0, -6.0), + central: ("npc.cockatrice.male.neck"), + ), + chest: ( + offset: (-5.5, -10.0, -9.5), + central: ("npc.cockatrice.male.chest"), + ), + tail_front: ( + offset: (-2.5, -9.0, -6.0), + central: ("npc.cockatrice.male.tail_front"), + ), + tail_rear: ( + offset: (-2.5, -13.0, -3.0), + central: ("npc.cockatrice.male.tail_rear"), + ) + ), + (Cockatrice, Female): ( + head: ( + offset: (-4.5, -6.0, -3.5), + central: ("npc.cockatrice.male.head"), + ), + beak: ( + offset: (-1.5, 0.0, -1.5), + central: ("npc.cockatrice.male.beak"), + ), + neck: ( + offset: (-3.5, 0.0, -6.0), + central: ("npc.cockatrice.male.neck"), + ), + chest: ( + offset: (-5.5, -10.0, -9.5), + central: ("npc.cockatrice.male.chest"), + ), + tail_front: ( + offset: (-2.5, -9.0, -6.0), + central: ("npc.cockatrice.male.tail_front"), + ), + tail_rear: ( + offset: (-2.5, -13.0, -3.0), + central: ("npc.cockatrice.male.tail_rear"), + ) + ), +}) diff --git a/assets/voxygen/voxel/bird_large_lateral_manifest.ron b/assets/voxygen/voxel/bird_large_lateral_manifest.ron new file mode 100644 index 0000000000..3eca741462 --- /dev/null +++ b/assets/voxygen/voxel/bird_large_lateral_manifest.ron @@ -0,0 +1,170 @@ +({ + (Phoenix, Male): ( + wing_in_l: ( + offset: (-10.0, -12.0, -1.5), + lateral: ("npc.phoenix.male.wing_in_r"), + ), + wing_in_r: ( + offset: (0.0, -12.0, -1.5), + lateral: ("npc.phoenix.male.wing_in_r"), + ), + wing_mid_l: ( + offset: (-7.0, -15.0, -0.5), + lateral: ("npc.phoenix.male.wing_mid_r"), + ), + wing_mid_r: ( + offset: (0.0, -15.0, -0.5), + lateral: ("npc.phoenix.male.wing_mid_r"), + ), + wing_out_l: ( + offset: (-18.0, -18.0, -2.0), + lateral: ("npc.phoenix.male.wing_out_r"), + ), + wing_out_r: ( + offset: (0.0, -18.0, -2.0), + lateral: ("npc.phoenix.male.wing_out_r"), + ), + leg_l: ( + offset: (-4.0, -5.0, -4.5), + lateral: ("npc.phoenix.male.leg_r"), + ), + leg_r: ( + offset: (-4.0, -5.0, -4.5), + lateral: ("npc.phoenix.male.leg_r"), + ), + foot_l: ( + offset: (-3.5, -4.5, -9.0), + lateral: ("npc.phoenix.male.foot_r"), + ), + foot_r: ( + offset: (-3.5, -4.5, -9.0), + lateral: ("npc.phoenix.male.foot_r"), + ) + ), + (Phoenix, Female): ( + wing_in_l: ( + offset: (-10.0, -12.0, -1.5), + lateral: ("npc.phoenix.male.wing_in_r"), + ), + wing_in_r: ( + offset: (0.0, -12.0, -1.5), + lateral: ("npc.phoenix.male.wing_in_r"), + ), + wing_mid_l: ( + offset: (-7.0, -15.0, -0.5), + lateral: ("npc.phoenix.male.wing_mid_r"), + ), + wing_mid_r: ( + offset: (0.0, -15.0, -0.5), + lateral: ("npc.phoenix.male.wing_mid_r"), + ), + wing_out_l: ( + offset: (-18.0, -18.0, -2.0), + lateral: ("npc.phoenix.male.wing_out_r"), + ), + wing_out_r: ( + offset: (0.0, -18.0, -2.0), + lateral: ("npc.phoenix.male.wing_out_r"), + ), + leg_l: ( + offset: (-4.0, -5.0, -4.5), + lateral: ("npc.phoenix.male.leg_r"), + ), + leg_r: ( + offset: (-4.0, -5.0, -4.5), + lateral: ("npc.phoenix.male.leg_r"), + ), + foot_l: ( + offset: (-3.5, -4.5, -9.0), + lateral: ("npc.phoenix.male.foot_r"), + ), + foot_r: ( + offset: (-3.5, -4.5, -9.0), + lateral: ("npc.phoenix.male.foot_r"), + ) + ), + (Cockatrice, Male): ( + wing_in_l: ( + offset: (-7.0, -8.0, -2.0), + lateral: ("npc.cockatrice.male.wing_in_r"), + ), + wing_in_r: ( + offset: (0.0, -8.0, -2.0), + lateral: ("npc.cockatrice.male.wing_in_r"), + ), + wing_mid_l: ( + offset: (-5.0, -9.0, -2.0), + lateral: ("npc.cockatrice.male.wing_mid_r"), + ), + wing_mid_r: ( + offset: (0.0, -9.0, -2.0), + lateral: ("npc.cockatrice.male.wing_mid_r"), + ), + wing_out_l: ( + offset: (-10.0, -11.0, -2.0), + lateral: ("npc.cockatrice.male.wing_out_r"), + ), + wing_out_r: ( + offset: (0.0, -11.0, -2.0), + lateral: ("npc.cockatrice.male.wing_out_r"), + ), + leg_l: ( + offset: (-3.0, -4.5, -4.0), + lateral: ("npc.cockatrice.male.leg_r"), + ), + leg_r: ( + offset: (-3.0, -4.5, -4.0), + lateral: ("npc.cockatrice.male.leg_r"), + ), + foot_l: ( + offset: (-3.5, -5.5, -10.0), + lateral: ("npc.cockatrice.male.foot_r"), + ), + foot_r: ( + offset: (-3.5, -5.5, -10.0), + lateral: ("npc.cockatrice.male.foot_r"), + ) + ), + (Cockatrice, Female): ( + wing_in_l: ( + offset: (-7.0, -8.0, -2.0), + lateral: ("npc.cockatrice.male.wing_in_r"), + ), + wing_in_r: ( + offset: (0.0, -8.0, -2.0), + lateral: ("npc.cockatrice.male.wing_in_r"), + ), + wing_mid_l: ( + offset: (-5.0, -9.0, -2.0), + lateral: ("npc.cockatrice.male.wing_mid_r"), + ), + wing_mid_r: ( + offset: (0.0, -9.0, -2.0), + lateral: ("npc.cockatrice.male.wing_mid_r"), + ), + wing_out_l: ( + offset: (-10.0, -11.0, -2.0), + lateral: ("npc.cockatrice.male.wing_out_r"), + ), + wing_out_r: ( + offset: (0.0, -11.0, -2.0), + lateral: ("npc.cockatrice.male.wing_out_r"), + ), + leg_l: ( + offset: (-3.0, -4.5, -4.0), + lateral: ("npc.cockatrice.male.leg_r"), + ), + leg_r: ( + offset: (-3.0, -4.5, -4.0), + lateral: ("npc.cockatrice.male.leg_r"), + ), + foot_l: ( + offset: (-3.5, -5.5, -10.0), + lateral: ("npc.cockatrice.male.foot_r"), + ), + foot_r: ( + offset: (-3.5, -5.5, -10.0), + lateral: ("npc.cockatrice.male.foot_r"), + ) + ), +}) \ No newline at end of file diff --git a/assets/voxygen/voxel/bird_medium_central_manifest.ron b/assets/voxygen/voxel/bird_medium_central_manifest.ron index 57d03ecfe1..d24a0be621 100644 --- a/assets/voxygen/voxel/bird_medium_central_manifest.ron +++ b/assets/voxygen/voxel/bird_medium_central_manifest.ron @@ -195,32 +195,4 @@ central: ("npc.parrot.male.tail"), ) ), - (Cockatrice, Male): ( - head: ( - offset: (-2.5, 0.0, -8.0), - central: ("npc.cockatrice.male.head"), - ), - torso: ( - offset: (-3.5, -6.5, -7.5), - central: ("npc.cockatrice.male.torso"), - ), - tail: ( - offset: (-1.5, -3.5, -4.0), - central: ("npc.cockatrice.male.tail"), - ) - ), - (Cockatrice, Female): ( - head: ( - offset: (-2.5, 0.0, -8.0), - central: ("npc.cockatrice.male.head"), - ), - torso: ( - offset: (-3.5, -6.5, -7.5), - central: ("npc.cockatrice.male.torso"), - ), - tail: ( - offset: (-1.5, -3.5, -4.0), - central: ("npc.cockatrice.male.tail"), - ) - ), }) \ No newline at end of file diff --git a/assets/voxygen/voxel/bird_medium_lateral_manifest.ron b/assets/voxygen/voxel/bird_medium_lateral_manifest.ron index 2bcb349b14..95c4027cc7 100644 --- a/assets/voxygen/voxel/bird_medium_lateral_manifest.ron +++ b/assets/voxygen/voxel/bird_medium_lateral_manifest.ron @@ -251,40 +251,4 @@ lateral: ("npc.parrot.male.leg_r"), ) ), - (Cockatrice, Male): ( - wing_l: ( - offset: (-2.0, -3.0, -9.0), - lateral: ("npc.cockatrice.male.wing_r"), - ), - wing_r: ( - offset: (-2.0, -3.0, -9.0), - lateral: ("npc.cockatrice.male.wing_r"), - ), - foot_l: ( - offset: (-2.5, 0.0, -12.0), - lateral: ("npc.cockatrice.male.leg_r"), - ), - foot_r: ( - offset: (-2.5, 0.0, -12.0), - lateral: ("npc.cockatrice.male.leg_r"), - ) - ), - (Cockatrice, Female): ( - wing_l: ( - offset: (-2.0, -3.0, -9.0), - lateral: ("npc.cockatrice.male.wing_r"), - ), - wing_r: ( - offset: (-2.0, -3.0, -9.0), - lateral: ("npc.cockatrice.male.wing_r"), - ), - foot_l: ( - offset: (-2.5, 0.0, -12.0), - lateral: ("npc.cockatrice.male.leg_r"), - ), - foot_r: ( - offset: (-2.5, 0.0, -12.0), - lateral: ("npc.cockatrice.male.leg_r"), - ) - ), }) \ No newline at end of file diff --git a/assets/voxygen/voxel/humanoid_lantern_manifest.ron b/assets/voxygen/voxel/humanoid_lantern_manifest.ron index 6b600a9cd3..c77d78b2eb 100644 --- a/assets/voxygen/voxel/humanoid_lantern_manifest.ron +++ b/assets/voxygen/voxel/humanoid_lantern_manifest.ron @@ -5,23 +5,23 @@ ), map: { "Green0": ( - vox_spec: ("armor.misc.lantern.green-0", (-2.0, -2.0, -7.0)), + vox_spec: ("lantern.green-0", (-2.0, -2.0, -7.0)), color: None ), "Black0": ( - vox_spec: ("armor.misc.lantern.black-0", (-2.0, -2.0, -7.0)), + vox_spec: ("lantern.black-0", (-2.0, -2.0, -8.5)), color: None ), "Red0": ( - vox_spec: ("armor.misc.lantern.red-0", (-2.0, -2.0, -7.0)), + vox_spec: ("lantern.red-0", (-2.0, -2.0, -7.0)), color: None ), "Blue0": ( - vox_spec: ("armor.misc.lantern.blue-0", (-2.0, -2.0, -7.0)), + vox_spec: ("lantern.blue-0", (-2.0, -2.0, -7.0)), color: None ), "GeodePurp": ( - vox_spec: ("lantern.geode_purp", (-3.0, -3.0, -7.0)), + vox_spec: ("lantern.geode_purp", (-2.5, -2.5, -9.5)), color: None ), }, diff --git a/assets/voxygen/voxel/lantern/black-0.vox b/assets/voxygen/voxel/lantern/black-0.vox index b71db60214..092a32a4d7 100644 --- a/assets/voxygen/voxel/lantern/black-0.vox +++ b/assets/voxygen/voxel/lantern/black-0.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6843626fd5bcb745ecfdc6e1c4341c89a3f84ad9a2d173ce38bc9786304e6402 -size 1892 +oid sha256:4c26b7302cb1889047d7498a482a5aa10b946d008ecbf699e74b7935a8cccd2b +size 1404 diff --git a/assets/voxygen/voxel/lantern/blue-0.vox b/assets/voxygen/voxel/lantern/blue-0.vox new file mode 100644 index 0000000000..1f9b3f481e --- /dev/null +++ b/assets/voxygen/voxel/lantern/blue-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74dce3eee748abc472024397e98332bb3673123d5e6e0bea2f8bfaea26afef56 +size 1404 diff --git a/assets/voxygen/voxel/lantern/geode_purp.vox b/assets/voxygen/voxel/lantern/geode_purp.vox index b2c7fc7e71..d580f94c66 100644 --- a/assets/voxygen/voxel/lantern/geode_purp.vox +++ b/assets/voxygen/voxel/lantern/geode_purp.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09a0300e03192fc8b5fe95f504ac896341f317456b28f6e0ee2c3541a16c8c78 -size 1500 +oid sha256:a0418a4af05e7d335a746074e725193d8c94dc2e0b41fb594218002e486ce194 +size 1476 diff --git a/assets/voxygen/voxel/lantern/green-0.vox b/assets/voxygen/voxel/lantern/green-0.vox index fa5e2c601f..0923c3d2cd 100644 --- a/assets/voxygen/voxel/lantern/green-0.vox +++ b/assets/voxygen/voxel/lantern/green-0.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec0492756972b9c934e660757f7ecdb2dbe5b6e99dddae42f178dd0e6c328bbb -size 1892 +oid sha256:de5f07bfee3fd6b9d9d387cc679b13a985addcdd2e1d1389019a9b28cde3d378 +size 1404 diff --git a/assets/voxygen/voxel/lantern/red-0.vox b/assets/voxygen/voxel/lantern/red-0.vox new file mode 100644 index 0000000000..0110b1a370 --- /dev/null +++ b/assets/voxygen/voxel/lantern/red-0.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:302f82c415f2f6cd2281355734cf4a20eea991b6c8eb179149fe0a6389433840 +size 1404 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/beak.vox b/assets/voxygen/voxel/npc/cockatrice/male/beak.vox new file mode 100644 index 0000000000..9146caa0b2 --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/beak.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cce54e7acf7b0a9551c816abff099a2cf1f6ae8676fd0b016d1359a4c1f3b320 +size 1232 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/chest.vox b/assets/voxygen/voxel/npc/cockatrice/male/chest.vox new file mode 100644 index 0000000000..9921765588 --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/chest.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01ec0fb420e315408a9b82df79adedc05abd081bf54659bc4a53cb500604a141 +size 6840 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/foot_r.vox b/assets/voxygen/voxel/npc/cockatrice/male/foot_r.vox new file mode 100644 index 0000000000..ef46bed01d --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6917f73529fa1631e248ef46665bcdc2811e8690678919149201b1655c57a493 +size 1588 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/head.vox b/assets/voxygen/voxel/npc/cockatrice/male/head.vox index 4df45a0d07..edd8c20ca6 100644 --- a/assets/voxygen/voxel/npc/cockatrice/male/head.vox +++ b/assets/voxygen/voxel/npc/cockatrice/male/head.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5103831b0b9c38ba8d8464266aa55da2b765cc5843a083cb8ce70f4cd9242c56 -size 1952 +oid sha256:835c2e4647b95ff4b583e50932522243bc6d5ac990d0e9fd4a09bbe69f53a395 +size 3112 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/leg_r.vox b/assets/voxygen/voxel/npc/cockatrice/male/leg_r.vox index e68e4781a1..23aca80aa3 100644 --- a/assets/voxygen/voxel/npc/cockatrice/male/leg_r.vox +++ b/assets/voxygen/voxel/npc/cockatrice/male/leg_r.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b95667bdfa3818583fa968a101f4bf39219f0488d4f7cf05f05374b7251ef3f6 -size 1364 +oid sha256:a11d94b3930ae2f50ba23f6d4c75e4d0fb590d7181e7df246c4e690babea366a +size 2224 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/neck.vox b/assets/voxygen/voxel/npc/cockatrice/male/neck.vox new file mode 100644 index 0000000000..be2fc102c5 --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/neck.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd52c35cb0670f77be4ed7a8a0a23968f12db49b7487abd6a6aea78d7162d50b +size 3424 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/tail.vox b/assets/voxygen/voxel/npc/cockatrice/male/tail.vox deleted file mode 100644 index dad94dedf5..0000000000 --- a/assets/voxygen/voxel/npc/cockatrice/male/tail.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0267a7da9724b1c8c6c7c2b7657d828897205af3c0c7b6d9a98861abf8f0baf8 -size 1216 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/tail_front.vox b/assets/voxygen/voxel/npc/cockatrice/male/tail_front.vox new file mode 100644 index 0000000000..f045ffb594 --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/tail_front.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bb5859c43e04522008a3961dbd804852fdd0a6d446a000d7b74934b3523ff9b +size 2056 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/tail_rear.vox b/assets/voxygen/voxel/npc/cockatrice/male/tail_rear.vox new file mode 100644 index 0000000000..ddb1b2f182 --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/tail_rear.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f251fa3447de8ba97da74c703c0ad8b5892167a4ec65ae5a4ad46fa946654aab +size 1772 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/torso.vox b/assets/voxygen/voxel/npc/cockatrice/male/torso.vox deleted file mode 100644 index a4c118f9b3..0000000000 --- a/assets/voxygen/voxel/npc/cockatrice/male/torso.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8fb4738f22d69176aea93efd95993f47e6a32cdd45c14435ef29bfd3f795fa46 -size 3048 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/wing_in_r.vox b/assets/voxygen/voxel/npc/cockatrice/male/wing_in_r.vox new file mode 100644 index 0000000000..95e2e1c4ce --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/wing_in_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bb7d1f8a8cb4108bb1787777a59fb8cd4bfb6e21ded2707515204dadd441f91 +size 1412 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/wing_mid_r.vox b/assets/voxygen/voxel/npc/cockatrice/male/wing_mid_r.vox new file mode 100644 index 0000000000..6daf0777bb --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/wing_mid_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1f1f5cb35b7026bdba42cfdc77f6cc8f505116550611e84ed41922c7a342166 +size 1408 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/wing_out_r.vox b/assets/voxygen/voxel/npc/cockatrice/male/wing_out_r.vox new file mode 100644 index 0000000000..37c70de238 --- /dev/null +++ b/assets/voxygen/voxel/npc/cockatrice/male/wing_out_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:074c1ced666ad7fcf6135d0424c12fb183aca5c022ba0e739be0bba422d5ada9 +size 1624 diff --git a/assets/voxygen/voxel/npc/cockatrice/male/wing_r.vox b/assets/voxygen/voxel/npc/cockatrice/male/wing_r.vox deleted file mode 100644 index 8ea51d1c13..0000000000 --- a/assets/voxygen/voxel/npc/cockatrice/male/wing_r.vox +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc0aed5d4195504288f7be8063bbb1e1058d7ae65bbd570ae97276b009c54318 -size 1212 diff --git a/assets/voxygen/voxel/npc/phoenix/male/beak.vox b/assets/voxygen/voxel/npc/phoenix/male/beak.vox new file mode 100644 index 0000000000..50b2c09489 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/beak.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d9f547cf2cb789ca4a8daa442657a41db25a91fe08594c8970083bf8e7ce7bc +size 1248 diff --git a/assets/voxygen/voxel/npc/phoenix/male/chest.vox b/assets/voxygen/voxel/npc/phoenix/male/chest.vox new file mode 100644 index 0000000000..0dd5d6650a --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/chest.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a985f025e429ca63f6570365addd8a128258119fe7eeef22c5f9c0bae0b3cada +size 8448 diff --git a/assets/voxygen/voxel/npc/phoenix/male/foot_r.vox b/assets/voxygen/voxel/npc/phoenix/male/foot_r.vox new file mode 100644 index 0000000000..076bc736c0 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8df02041d931946f0a053c24faebcacaccb5de301c42b4a32df06e798bad5d5b +size 1628 diff --git a/assets/voxygen/voxel/npc/phoenix/male/head.vox b/assets/voxygen/voxel/npc/phoenix/male/head.vox new file mode 100644 index 0000000000..6db2f6d043 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/head.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:022ea7752438f738ebd2bb47f68ff827cb6c8f85fab05dc4286e01f31102e482 +size 3392 diff --git a/assets/voxygen/voxel/npc/phoenix/male/leg_r.vox b/assets/voxygen/voxel/npc/phoenix/male/leg_r.vox new file mode 100644 index 0000000000..e2f83fba5e --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/leg_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59bec4734dd00e6fed8320b68e7f9a33be3956105ef78994d6ed689512e200e5 +size 2644 diff --git a/assets/voxygen/voxel/npc/phoenix/male/neck.vox b/assets/voxygen/voxel/npc/phoenix/male/neck.vox new file mode 100644 index 0000000000..3c47ead3e8 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/neck.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:091faef09b43d101a523ef5b46a74c4754057ecbf20d7ed3d9f8c609b7b4a7f1 +size 4536 diff --git a/assets/voxygen/voxel/npc/phoenix/male/tail_front.vox b/assets/voxygen/voxel/npc/phoenix/male/tail_front.vox new file mode 100644 index 0000000000..62436cadc9 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/tail_front.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:234c8e396b9cace8165d9118793817df5a8ff78140b700cb5b655ef5df326ac8 +size 2768 diff --git a/assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox b/assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox new file mode 100644 index 0000000000..3da4400bf0 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77ea457f336df7c1321c89279d061c2e278455743810027dbea19064f59b7c53 +size 3032 diff --git a/assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox b/assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox new file mode 100644 index 0000000000..33ac105cb6 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f0fc4eaebdd0dfbdceecd73f4bbef61df1ad41a4f02e74466fe38e4d73ef81a +size 1840 diff --git a/assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox b/assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox new file mode 100644 index 0000000000..eaf3532512 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:476c07d679d1fe9ca356390ea16da02f843ed94637e767bff4fa2e875bc09ad4 +size 1748 diff --git a/assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox b/assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox new file mode 100644 index 0000000000..7d4af77900 --- /dev/null +++ b/assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:085ca80b33c9b0962a4b8614fa17211abae68c0b13b9e7f0044e6109b3d8c429 +size 2648 diff --git a/assets/voxygen/voxel/sprite/cooking_pot/pot-0.vox b/assets/voxygen/voxel/sprite/cooking_pot/pot-0.vox index 14e9a3c62f..e96703828c 100644 --- a/assets/voxygen/voxel/sprite/cooking_pot/pot-0.vox +++ b/assets/voxygen/voxel/sprite/cooking_pot/pot-0.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e616ae51d56fd59d500371e7b1341dbb46352b7e367168dd0e4988ce539e3847 -size 8340 +oid sha256:51e5ea3789ec7f118a8ca9022129371e8bf9b4143f57e8d117f96d60b7711892 +size 5884 diff --git a/client/Cargo.toml b/client/Cargo.toml index 8f7619c628..e0113e12f2 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Joshua Barretto "] edition = "2018" [features] -tracy = ["common/tracy", "common-base/tracy", "common-sys/tracy", "common-net/tracy", "common-frontend/tracy"] +tracy = ["common/tracy", "common-base/tracy", "common-state/tracy", "common-systems/tracy", "common-net/tracy", "common-frontend/tracy"] simd = ["vek/platform_intrinsics"] plugins = ["common-state/plugins"] bin_bot = ["common-ecs", "serde", "ron", "clap", "rustyline", "common-frontend", "async-channel"] @@ -16,7 +16,7 @@ default = ["simd"] common = { package = "veloren-common", path = "../common", features = ["no-assets"] } common-base = { package = "veloren-common-base", path = "../common/base" } common-state = { package = "veloren-common-state", path = "../common/state", default-features = false } -common-sys = { package = "veloren-common-sys", path = "../common/sys", default-features = false } +common-systems = { package = "veloren-common-systems", path = "../common/systems", default-features = false } common-net = { package = "veloren-common-net", path = "../common/net" } network = { package = "veloren-network", path = "../network", features = ["compression"], default-features = false } @@ -32,6 +32,7 @@ vek = { version = "=0.14.1", features = ["serde"] } hashbrown = { version = "0.9", features = ["rayon", "serde", "nightly"] } authc = { git = "https://gitlab.com/veloren/auth.git", rev = "fb3dcbc4962b367253f8f2f92760ef44d2679c9a" } +#TODO: put bot in a different crate #bot only async-channel = { version = "1.6", optional = true } common-ecs = { package = "veloren-common-ecs", path = "../common/ecs", optional = true } diff --git a/client/examples/chat-cli/main.rs b/client/examples/chat-cli/main.rs index 9266ac2932..2d7f7f210e 100644 --- a/client/examples/chat-cli/main.rs +++ b/client/examples/chat-cli/main.rs @@ -52,7 +52,7 @@ fn main() { let addr = ConnectionArgs::resolve(&server_addr, false) .await .expect("dns resolve failed"); - Client::new(addr, None, runtime2).await + Client::new(addr, None, runtime2, &mut None).await }) .expect("Failed to create client instance"); diff --git a/client/src/bin/bot/main.rs b/client/src/bin/bot/main.rs index a9ae28f1e8..7cb0aaab38 100644 --- a/client/src/bin/bot/main.rs +++ b/client/src/bin/bot/main.rs @@ -59,7 +59,7 @@ pub fn make_client(runtime: &Arc, server: &str) -> Client { let connection_args = ConnectionArgs::resolve(server, false) .await .expect("DNS resolution failed"); - Client::new(connection_args, view_distance, runtime2) + Client::new(connection_args, view_distance, runtime2, &mut None) .await .expect("Failed to connect to server") }) diff --git a/client/src/lib.rs b/client/src/lib.rs index 5f225758bc..a9e1fc582a 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -9,6 +9,7 @@ pub mod error; // Reexports pub use crate::error::Error; pub use authc::AuthClientError; +pub use common_net::msg::ServerInfo; pub use specs::{ join::Join, saveload::{Marker, MarkerAllocator}, @@ -49,13 +50,13 @@ use common_net::{ world_msg::{EconomyInfo, SiteId, SiteInfo}, ChatMsgValidationError, ClientGeneral, ClientMsg, ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg, PlayerInfo, PlayerListUpdate, - PresenceKind, RegisterError, ServerGeneral, ServerInfo, ServerInit, ServerRegisterAnswer, + PresenceKind, RegisterError, ServerGeneral, ServerInit, ServerRegisterAnswer, MAX_BYTES_CHAT_MSG, }, sync::WorldSyncExt, }; use common_state::State; -use common_sys::add_local_systems; +use common_systems::add_local_systems; use comp::BuffKind; use futures_util::FutureExt; use hashbrown::{HashMap, HashSet}; @@ -66,6 +67,7 @@ use rayon::prelude::*; use specs::Component; use std::{ collections::{BTreeMap, VecDeque}, + mem, sync::Arc, time::{Duration, Instant}, }; @@ -204,6 +206,8 @@ impl Client { addr: ConnectionArgs, view_distance: Option, runtime: Arc, + // TODO: refactor to avoid needing to use this out parameter + mismatched_server_info: &mut Option, ) -> Result { let network = Network::new(Pid::new(), &runtime); @@ -235,8 +239,6 @@ impl Client { register_stream.send(ClientType::Game)?; let server_info: ServerInfo = register_stream.recv().await?; - - // TODO: Display that versions don't match in Voxygen if server_info.git_hash != *common::util::GIT_HASH { warn!( "Server is running {}[{}], you are running {}[{}], versions might be incompatible!", @@ -245,6 +247,10 @@ impl Client { common::util::GIT_HASH.to_string(), common::util::GIT_DATE.to_string(), ); + + // Pass the server info back to the caller to ensure they can access it even + // if this function errors. + mem::swap(mismatched_server_info, &mut Some(server_info.clone())); } debug!("Auth Server: {:?}", server_info.auth_provider); @@ -1923,15 +1929,17 @@ impl Client { fn handle_server_terrain_msg(&mut self, msg: ServerGeneral) -> Result<(), Error> { match msg { ServerGeneral::TerrainChunkUpdate { key, chunk } => { - if let Ok(chunk) = chunk { - self.state.insert_chunk(key, *chunk); + if let Some(chunk) = chunk.ok().and_then(|c| c.decompress()) { + self.state.insert_chunk(key, Arc::new(chunk)); } self.pending_chunks.remove(&key); }, - ServerGeneral::TerrainBlockUpdates(mut blocks) => { - blocks.drain().for_each(|(pos, block)| { - self.state.set_block(pos, block); - }); + ServerGeneral::TerrainBlockUpdates(blocks) => { + if let Some(mut blocks) = blocks.decompress() { + blocks.drain().for_each(|(pos, block)| { + self.state.set_block(pos, block); + }); + } }, _ => unreachable!("Not a terrain message"), } @@ -2447,6 +2455,7 @@ mod tests { ConnectionArgs::IpAndPort(vec![socket]), view_distance, runtime2, + &mut None, )); let _ = veloren_client.map(|mut client| { diff --git a/common/net/Cargo.toml b/common/net/Cargo.toml index 209c2d6a18..0661f79697 100644 --- a/common/net/Cargo.toml +++ b/common/net/Cargo.toml @@ -14,6 +14,8 @@ default = ["simd"] common = {package = "veloren-common", path = "../../common"} #inline_tweak = "1.0.2" +bincode = "1.3.3" +flate2 = "1.0.20" sum_type = "0.2.0" vek = { version = "=0.14.1", features = ["serde"] } tracing = { version = "0.1", default-features = false } diff --git a/common/net/src/msg/mod.rs b/common/net/src/msg/mod.rs index 667038ac78..2d2421f9cc 100644 --- a/common/net/src/msg/mod.rs +++ b/common/net/src/msg/mod.rs @@ -15,6 +15,8 @@ pub use self::{ }; use common::character::CharacterId; use serde::{Deserialize, Serialize}; +use std::marker::PhantomData; +use tracing::trace; #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] pub enum PresenceKind { @@ -42,3 +44,60 @@ pub fn validate_chat_msg(msg: &str) -> Result<(), ChatMsgValidationError> { Err(ChatMsgValidationError::TooLong) } } + +/// Wrapper for compressed, serialized data (for stuff that doesn't use the +/// default lz4 compression) +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CompressedData { + pub data: Vec, + compressed: bool, + _phantom: PhantomData, +} + +impl Deserialize<'a>> CompressedData { + pub fn compress(t: &T, level: u32) -> Self { + use flate2::{write::DeflateEncoder, Compression}; + use std::io::Write; + let uncompressed = bincode::serialize(t) + .expect("bincode serialization can only fail if a byte limit is set"); + + if uncompressed.len() >= 32 { + const EXPECT_MSG: &str = + "compression only fails for fallible Read/Write impls (which Vec is not)"; + + let mut encoder = DeflateEncoder::new(Vec::new(), Compression::new(level)); + encoder.write_all(&*uncompressed).expect(EXPECT_MSG); + let compressed = encoder.finish().expect(EXPECT_MSG); + trace!( + "compressed {}, uncompressed {}, ratio {}", + compressed.len(), + uncompressed.len(), + compressed.len() as f32 / uncompressed.len() as f32 + ); + CompressedData { + data: compressed, + compressed: true, + _phantom: PhantomData, + } + } else { + CompressedData { + data: uncompressed, + compressed: false, + _phantom: PhantomData, + } + } + } + + pub fn decompress(&self) -> Option { + use std::io::Read; + if self.compressed { + let mut uncompressed = Vec::new(); + flate2::read::DeflateDecoder::new(&*self.data) + .read_to_end(&mut uncompressed) + .ok()?; + bincode::deserialize(&*uncompressed).ok() + } else { + bincode::deserialize(&*self.data).ok() + } + } +} diff --git a/common/net/src/msg/server.rs b/common/net/src/msg/server.rs index 9eabad35ca..033ed0892e 100644 --- a/common/net/src/msg/server.rs +++ b/common/net/src/msg/server.rs @@ -1,4 +1,4 @@ -use super::{world_msg::EconomyInfo, ClientType, EcsCompPacket, PingMsg}; +use super::{world_msg::EconomyInfo, ClientType, CompressedData, EcsCompPacket, PingMsg}; use crate::sync; use common::{ character::{self, CharacterItem}, @@ -106,9 +106,9 @@ pub enum ServerGeneral { // Ingame related AND terrain stream TerrainChunkUpdate { key: Vec2, - chunk: Result, ()>, + chunk: Result, ()>, }, - TerrainBlockUpdates(HashMap, Block>), + TerrainBlockUpdates(CompressedData, Block>>), // Always possible PlayerListUpdate(PlayerListUpdate), /// A message to go into the client chat box. The client is responsible for diff --git a/common/src/assets.rs b/common/src/assets.rs index cf016cdca2..737810da46 100644 --- a/common/src/assets.rs +++ b/common/src/assets.rs @@ -26,6 +26,7 @@ lazy_static! { pub fn start_hot_reloading() { ASSETS.enhance_hot_reloading(); } pub type AssetHandle = assets_manager::Handle<'static, T>; +pub type AssetGuard = assets_manager::AssetGuard<'static, T>; pub type AssetDir = assets_manager::DirReader<'static, T, source::FileSystem>; /// The Asset trait, which is implemented by all structures that have their data diff --git a/common/src/cached_spatial_grid.rs b/common/src/cached_spatial_grid.rs new file mode 100644 index 0000000000..92b453868f --- /dev/null +++ b/common/src/cached_spatial_grid.rs @@ -0,0 +1,21 @@ +use crate::util::SpatialGrid; + +/// Cached [`SpatialGrid`] for reuse within different ecs systems during a tick. +/// This is used to accelerate queries on entities within a specific area. +/// Updated within the physics system [`crate::sys::phys::Sys`] after new entity +/// positions are calculated for the tick. So any position modifications outside +/// the physics system will not be reflected here until the next tick when the +/// physics system runs. +pub struct CachedSpatialGrid(pub SpatialGrid); + +impl Default for CachedSpatialGrid { + fn default() -> Self { + let lg2_cell_size = 5; // 32 + let lg2_large_cell_size = 6; // 64 + let radius_cutoff = 8; + + let spatial_grid = SpatialGrid::new(lg2_cell_size, lg2_large_cell_size, radius_cutoff); + + Self(spatial_grid) + } +} diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index a777055891..237a480119 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -38,6 +38,8 @@ pub enum Tactic { FixedTurret, RotatingTurret, Mindflayer, + BirdLargeBreathe, + BirdLargeFire, } #[derive(Copy, Clone, Debug, PartialEq)] @@ -247,7 +249,7 @@ impl<'a> From<&'a Body> for Psyche { }, Body::BipedSmall(_) => 0.5, Body::BirdMedium(_) => 0.5, - Body::BirdSmall(_) => 0.4, + Body::BirdLarge(_) => 0.9, Body::FishMedium(_) => 0.15, Body::FishSmall(_) => 0.0, Body::BipedLarge(_) => 1.0, diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 4da8d22f83..1fe48767b6 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -1,7 +1,7 @@ pub mod biped_large; pub mod biped_small; +pub mod bird_large; pub mod bird_medium; -pub mod bird_small; pub mod dragon; pub mod fish_medium; pub mod fish_small; @@ -38,7 +38,7 @@ make_case_elim!( BirdMedium(body: bird_medium::Body) = 3, FishMedium(body: fish_medium::Body) = 4, Dragon(body: dragon::Body) = 5, - BirdSmall(body: bird_small::Body) = 6, + BirdLarge(body: bird_large::Body) = 6, FishSmall(body: fish_small::Body) = 7, BipedLarge(body: biped_large::Body)= 8, BipedSmall(body: biped_small::Body)= 9, @@ -73,7 +73,7 @@ pub struct AllBodies { pub bird_medium: BodyData>, pub fish_medium: BodyData>, pub dragon: BodyData>, - pub bird_small: BodyData, + pub bird_large: BodyData>, pub fish_small: BodyData>, pub biped_large: BodyData>, pub biped_small: BodyData>, @@ -95,6 +95,7 @@ impl core::ops::Index for AllBodies &self.quadruped_small.body, NpcKind::Wolf => &self.quadruped_medium.body, NpcKind::Duck => &self.bird_medium.body, + NpcKind::Phoenix => &self.bird_large.body, NpcKind::Marlin => &self.fish_medium.body, NpcKind::Clownfish => &self.fish_small.body, NpcKind::Ogre => &self.biped_large.body, @@ -118,9 +119,9 @@ impl<'a, BodyMeta, SpeciesMeta> core::ops::Index<&'a Body> for AllBodies &self.quadruped_small.body, Body::QuadrupedMedium(_) => &self.quadruped_medium.body, Body::BirdMedium(_) => &self.bird_medium.body, + Body::BirdLarge(_) => &self.bird_large.body, Body::FishMedium(_) => &self.fish_medium.body, Body::Dragon(_) => &self.dragon.body, - Body::BirdSmall(_) => &self.bird_small.body, Body::FishSmall(_) => &self.fish_small.body, Body::BipedLarge(_) => &self.biped_large.body, Body::BipedSmall(_) => &self.biped_small.body, @@ -152,7 +153,7 @@ impl Body { let d = match self { // based on a house sparrow (Passer domesticus) Body::BirdMedium(_) => 700.0, - Body::BirdSmall(_) => 700.0, + Body::BirdLarge(_) => 2_200.0, // based on its mass divided by the volume of a bird scaled up to the size of the dragon Body::Dragon(_) => 3_700.0, @@ -183,8 +184,7 @@ impl Body { // ravens are 0.69-2 kg, crows are 0.51 kg on average Body::BirdMedium(_) => 1.0, - // australian magpies are around 0.22-0.35 kg - Body::BirdSmall(_) => 0.3, + Body::BirdLarge(_) => 200.0, Body::Dragon(_) => 20_000.0, Body::FishMedium(_) => 2.5, @@ -281,11 +281,8 @@ impl Body { _ => Vec3::new(4.6, 3.0, 6.0), }, Body::BipedSmall(_) => Vec3::new(1.0, 0.75, 1.4), - Body::BirdMedium(body) => match body.species { - bird_medium::Species::Cockatrice => Vec3::new(2.0, 1.0, 1.8), - _ => Vec3::new(2.0, 1.0, 1.1), - }, - Body::BirdSmall(_) => Vec3::new(1.2, 0.6, 1.1), + Body::BirdMedium(_) => Vec3::new(2.0, 1.0, 1.1), + Body::BirdLarge(_) => Vec3::new(2.0, 5.0, 2.4), Body::Dragon(_) => Vec3::new(16.0, 10.0, 16.0), Body::FishMedium(_) => Vec3::new(0.5, 2.0, 0.8), Body::FishSmall(_) => Vec3::new(0.3, 1.2, 0.6), @@ -374,6 +371,10 @@ impl Body { biped_large::Species::Dullahan => 4000, _ => 3000, }, + Body::BirdLarge(body) => match body.species { + bird_large::Species::Cockatrice => 4000, + bird_large::Species::Phoenix => 6000, + }, Body::Humanoid(_) => 750, _ => 1000, } @@ -429,13 +430,12 @@ impl Body { bird_medium::Species::Goose => 60, bird_medium::Species::Parrot => 60, bird_medium::Species::Peacock => 60, - bird_medium::Species::Cockatrice => 400, bird_medium::Species::Eagle => 400, _ => 100, }, Body::FishMedium(_) => 50, Body::Dragon(_) => 5000, - Body::BirdSmall(_) => 50, + Body::BirdLarge(_) => 3000, Body::FishSmall(_) => 20, Body::BipedLarge(biped_large) => match biped_large.species { biped_large::Species::Ogre => 2500, @@ -542,13 +542,12 @@ impl Body { bird_medium::Species::Goose => 10, bird_medium::Species::Parrot => 10, bird_medium::Species::Peacock => 10, - bird_medium::Species::Cockatrice => 10, bird_medium::Species::Eagle => 10, _ => 20, }, Body::FishMedium(_) => 10, Body::Dragon(_) => 500, - Body::BirdSmall(_) => 10, + Body::BirdLarge(_) => 120, Body::FishSmall(_) => 10, Body::BipedLarge(biped_large) => match biped_large.species { biped_large::Species::Ogre => 70, @@ -587,7 +586,7 @@ impl Body { pub fn flying_height(&self) -> f32 { match self { - Body::BirdSmall(_) => 30.0, + Body::BirdLarge(_) => 50.0, Body::BirdMedium(_) => 40.0, Body::Dragon(_) => 60.0, Body::Ship(ship::Body::DefaultAirship) => 60.0, diff --git a/common/src/comp/body/bird_large.rs b/common/src/comp/body/bird_large.rs new file mode 100644 index 0000000000..629317082a --- /dev/null +++ b/common/src/comp/body/bird_large.rs @@ -0,0 +1,82 @@ +use crate::{make_case_elim, make_proj_elim}; +use rand::{seq::SliceRandom, thread_rng}; +use serde::{Deserialize, Serialize}; + +make_proj_elim!( + body, + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] + pub struct Body { + pub species: Species, + pub body_type: BodyType, + } +); + +impl Body { + pub fn random() -> Self { + let mut rng = thread_rng(); + let species = *(&ALL_SPECIES).choose(&mut rng).unwrap(); + Self::random_with(&mut rng, &species) + } + + #[inline] + pub fn random_with(rng: &mut impl rand::Rng, &species: &Species) -> Self { + let body_type = *(&ALL_BODY_TYPES).choose(rng).unwrap(); + Self { species, body_type } + } +} + +impl From for super::Body { + fn from(body: Body) -> Self { super::Body::BirdLarge(body) } +} + +make_case_elim!( + species, + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] + #[repr(u32)] + pub enum Species { + Phoenix = 0, + Cockatrice = 1, + } +); + +/// Data representing per-species generic data. +/// +/// NOTE: Deliberately don't (yet?) implement serialize. +#[derive(Clone, Debug, Deserialize)] +pub struct AllSpecies { + pub phoenix: SpeciesMeta, + pub cockatrice: SpeciesMeta, +} + +impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies { + type Output = SpeciesMeta; + + #[inline] + fn index(&self, &index: &'a Species) -> &Self::Output { + match index { + Species::Phoenix => &self.phoenix, + Species::Cockatrice => &self.cockatrice, + } + } +} + +pub const ALL_SPECIES: [Species; 2] = [Species::Phoenix, Species::Cockatrice]; + +impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies { + type IntoIter = std::iter::Copied>; + type Item = Species; + + fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() } +} + +make_case_elim!( + body_type, + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] + #[repr(u32)] + pub enum BodyType { + Female = 0, + Male = 1, + } +); + +pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male]; diff --git a/common/src/comp/body/bird_medium.rs b/common/src/comp/body/bird_medium.rs index 264e6abf05..5eb7dbee65 100644 --- a/common/src/comp/body/bird_medium.rs +++ b/common/src/comp/body/bird_medium.rs @@ -41,7 +41,6 @@ make_case_elim!( Eagle = 4, Owl = 5, Parrot = 6, - Cockatrice = 7, } ); @@ -57,7 +56,6 @@ pub struct AllSpecies { pub eagle: SpeciesMeta, pub owl: SpeciesMeta, pub parrot: SpeciesMeta, - pub cockatrice: SpeciesMeta, } impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies { @@ -73,12 +71,11 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies Species::Eagle => &self.eagle, Species::Owl => &self.owl, Species::Parrot => &self.parrot, - Species::Cockatrice => &self.cockatrice, } } } -pub const ALL_SPECIES: [Species; 8] = [ +pub const ALL_SPECIES: [Species; 7] = [ Species::Duck, Species::Chicken, Species::Goose, @@ -86,7 +83,6 @@ pub const ALL_SPECIES: [Species; 8] = [ Species::Eagle, Species::Owl, Species::Parrot, - Species::Cockatrice, ]; impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies { diff --git a/common/src/comp/body/bird_small.rs b/common/src/comp/body/bird_small.rs deleted file mode 100644 index a3be8c3087..0000000000 --- a/common/src/comp/body/bird_small.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::{make_case_elim, make_proj_elim}; -use rand::{seq::SliceRandom, thread_rng}; -use serde::{Deserialize, Serialize}; - -make_proj_elim!( - body, - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] - pub struct Body { - pub head: Head, - pub torso: Torso, - pub wing_l: WingL, - pub wing_r: WingR, - } -); - -impl Body { - pub fn random() -> Self { - let mut rng = thread_rng(); - Self { - head: *(&ALL_HEADS).choose(&mut rng).unwrap(), - torso: *(&ALL_TORSOS).choose(&mut rng).unwrap(), - wing_l: *(&ALL_WING_LS).choose(&mut rng).unwrap(), - wing_r: *(&ALL_WING_RS).choose(&mut rng).unwrap(), - } - } -} - -make_case_elim!( - head, - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] - #[repr(u32)] - pub enum Head { - Default = 0, - } -); -const ALL_HEADS: [Head; 1] = [Head::Default]; - -make_case_elim!( - torso, - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] - #[repr(u32)] - pub enum Torso { - Default = 0, - } -); -const ALL_TORSOS: [Torso; 1] = [Torso::Default]; - -make_case_elim!( - wing_l, - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] - #[repr(u32)] - pub enum WingL { - Default = 0, - } -); -const ALL_WING_LS: [WingL; 1] = [WingL::Default]; - -make_case_elim!( - wing_r, - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] - #[repr(u32)] - pub enum WingR { - Default = 0, - } -); -const ALL_WING_RS: [WingR; 1] = [WingR::Default]; diff --git a/common/src/comp/body/ship.rs b/common/src/comp/body/ship.rs index c67085acce..f880683d47 100644 --- a/common/src/comp/body/ship.rs +++ b/common/src/comp/body/ship.rs @@ -54,12 +54,9 @@ impl Body { pub fn mass(&self) -> Mass { Mass((self.hull_vol() + self.balloon_vol()) * self.density().0) } } -/// Terrain is 11.0 scale relative to small-scale voxels, and all figures get -/// multiplied by 0.8 in rendering. For now, have a constant in `comp::Scale` -/// that compensates for both of these, but there might be a more elegant way -/// (e.g. using `Scale(0.8)` for everything else and not having a magic number -/// in figure rendering, and multiplying terrain models by 11.0 in animation). -pub const AIRSHIP_SCALE: f32 = 11.0 / 0.8; +/// Terrain is 11.0 scale relative to small-scale voxels, +/// airship scale is multiplied by 11 to reach terrain scale. +pub const AIRSHIP_SCALE: f32 = 11.0; /// Duplicate of some of the things defined in `voxygen::scene::figure::load` to /// avoid having to refactor all of that to `common` for using voxels as diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 587b3f5b1f..40414c39ad 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -167,6 +167,19 @@ impl CharacterState { ) } + pub fn is_using_hands(&self) -> bool { + matches!( + self, + CharacterState::Climb(_) + | CharacterState::Equipping(_) + | CharacterState::Dance + | CharacterState::Glide + | CharacterState::GlideWield + | CharacterState::Talk + | CharacterState::Roll(_), + ) + } + pub fn is_block(&self) -> bool { matches!(self, CharacterState::BasicBlock) } pub fn is_dodge(&self) -> bool { matches!(self, CharacterState::Roll(_)) } diff --git a/common/src/comp/fluid_dynamics.rs b/common/src/comp/fluid_dynamics.rs index 6e5a688240..6508160168 100644 --- a/common/src/comp/fluid_dynamics.rs +++ b/common/src/comp/fluid_dynamics.rs @@ -129,11 +129,11 @@ impl Body { }, // Cross-section, zero-lift angle; exclude the wings (width * 0.2) - Body::BirdMedium(_) | Body::BirdSmall(_) | Body::Dragon(_) => { + Body::BirdMedium(_) | Body::BirdLarge(_) | Body::Dragon(_) => { let dim = self.dimensions().map(|a| a * 0.5); let cd = match self { Body::BirdMedium(_) => 0.2, - Body::BirdSmall(_) => 0.4, + Body::BirdLarge(_) => 0.4, _ => 0.7, }; cd * std::f32::consts::PI * dim.x * 0.2 * dim.z @@ -149,6 +149,7 @@ impl Body { // very streamlined objects object::Body::Arrow | object::Body::ArrowSnake + | object::Body::ArrowTurret | object::Body::FireworkBlue | object::Body::FireworkGreen | object::Body::FireworkPurple diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index f9c0701742..9bf489e6e8 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -441,4 +441,6 @@ pub enum UniqueKind { ObjectTurret, WoodenSpear, MindflayerStaff, + BirdLargeBreathe, + BirdLargeFire, } diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 6e7668d62c..e1fb785727 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -1,6 +1,6 @@ use crate::{ comp::{ - biped_large, biped_small, golem, + biped_large, biped_small, bird_large, golem, inventory::{ loadout::Loadout, slot::{ArmorSlot, EquipSlot}, @@ -333,6 +333,18 @@ impl LoadoutBuilder { )); }, }, + Body::BirdLarge(bird_large) => match (bird_large.species, bird_large.body_type) { + (bird_large::Species::Cockatrice, _) => { + main_tool = Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.birdlargebreathe", + )); + }, + (bird_large::Species::Phoenix, _) => { + main_tool = Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.birdlargefire", + )); + }, + }, _ => {}, }; } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 2c3664a2c7..5f563a3836 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -50,7 +50,7 @@ pub use self::{ aura::{Aura, AuraChange, AuraKind, Auras}, beam::{Beam, BeamSegment}, body::{ - biped_large, biped_small, bird_medium, bird_small, dragon, fish_medium, fish_small, golem, + biped_large, biped_small, bird_large, bird_medium, dragon, fish_medium, fish_small, golem, humanoid, object, quadruped_low, quadruped_medium, quadruped_small, ship, theropod, AllBodies, Body, BodyData, }, diff --git a/common/src/generation.rs b/common/src/generation.rs index 9b187ecc05..e922f604c7 100644 --- a/common/src/generation.rs +++ b/common/src/generation.rs @@ -135,6 +135,7 @@ impl EntityInfo { Some(get_npc_name(&npc_names.quadruped_medium, body.species)) }, Body::BirdMedium(body) => Some(get_npc_name(&npc_names.bird_medium, body.species)), + Body::BirdLarge(body) => Some(get_npc_name(&npc_names.bird_large, body.species)), Body::FishSmall(body) => Some(get_npc_name(&npc_names.fish_small, body.species)), Body::FishMedium(body) => Some(get_npc_name(&npc_names.fish_medium, body.species)), Body::Theropod(body) => Some(get_npc_name(&npc_names.theropod, body.species)), diff --git a/common/src/lib.rs b/common/src/lib.rs index c78e861453..d4d8f6a094 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -26,6 +26,8 @@ pub use uuid; pub mod assets; #[cfg(not(target_arch = "wasm32"))] pub mod astar; #[cfg(not(target_arch = "wasm32"))] +mod cached_spatial_grid; +#[cfg(not(target_arch = "wasm32"))] pub mod character; #[cfg(not(target_arch = "wasm32"))] pub mod clock; #[cfg(not(target_arch = "wasm32"))] pub mod cmd; @@ -78,6 +80,8 @@ pub mod uid; #[cfg(not(target_arch = "wasm32"))] pub mod volumes; +#[cfg(not(target_arch = "wasm32"))] +pub use cached_spatial_grid::CachedSpatialGrid; pub use combat::DamageSource; #[cfg(not(target_arch = "wasm32"))] pub use combat::{Damage, GroupTarget, Knockback, KnockbackDir}; diff --git a/common/src/npc.rs b/common/src/npc.rs index d7eebe5f17..5712c33696 100644 --- a/common/src/npc.rs +++ b/common/src/npc.rs @@ -13,6 +13,7 @@ pub enum NpcKind { Wolf, Pig, Duck, + Phoenix, Clownfish, Marlin, Ogre, @@ -23,11 +24,12 @@ pub enum NpcKind { Crocodile, } -pub const ALL_NPCS: [NpcKind; 12] = [ +pub const ALL_NPCS: [NpcKind; 13] = [ NpcKind::Humanoid, NpcKind::Wolf, NpcKind::Pig, NpcKind::Duck, + NpcKind::Phoenix, NpcKind::Clownfish, NpcKind::Marlin, NpcKind::Ogre, @@ -122,6 +124,7 @@ pub fn kind_to_body(kind: NpcKind) -> Body { NpcKind::Pig => comp::quadruped_small::Body::random().into(), NpcKind::Wolf => comp::quadruped_medium::Body::random().into(), NpcKind::Duck => comp::bird_medium::Body::random().into(), + NpcKind::Phoenix => comp::bird_large::Body::random().into(), NpcKind::Clownfish => comp::fish_small::Body::random().into(), NpcKind::Marlin => comp::fish_medium::Body::random().into(), NpcKind::Ogre => comp::biped_large::Body::random().into(), @@ -228,6 +231,14 @@ impl NpcBody { comp::bird_medium::Body::random_with, ) }) + .or_else(|| { + parse( + s, + NpcKind::Phoenix, + &npc_names.bird_large, + comp::bird_large::Body::random_with, + ) + }) .or_else(|| { parse( s, diff --git a/common/src/states/basic_beam.rs b/common/src/states/basic_beam.rs index 766959470f..ca700bf91b 100644 --- a/common/src/states/basic_beam.rs +++ b/common/src/states/basic_beam.rs @@ -3,7 +3,7 @@ use crate::{ Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement, Damage, DamageSource, GroupTarget, }, - comp::{beam, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate}, + comp::{beam, Body, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate}, event::ServerEvent, states::{ behavior::{CharacterBehavior, JoinData}, @@ -136,11 +136,15 @@ impl CharacterBehavior for Data { owner: Some(*data.uid), specifier: self.static_data.specifier, }; + let body_offsets_z = match data.body { + Body::BirdLarge(_) => data.body.height() * 0.9, + _ => data.body.height() * 0.5, + }; // Gets offsets let body_offsets = Vec3::new( - (data.body.radius() + 0.2) * data.inputs.look_dir.x, - (data.body.radius() + 0.2) * data.inputs.look_dir.y, - data.body.eye_height() * 0.6, + (data.body.radius() + 1.0) * data.inputs.look_dir.x, + (data.body.radius() + 1.0) * data.inputs.look_dir.y, + body_offsets_z, ); let pos = Pos(data.pos.0 + body_offsets); // Create beam segment diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 654fa44ade..245169fc3b 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -77,7 +77,7 @@ impl Body { Body::BirdMedium(_) => 80.0, Body::FishMedium(_) => 80.0, Body::Dragon(_) => 250.0, - Body::BirdSmall(_) => 75.0, + Body::BirdLarge(_) => 110.0, Body::FishSmall(_) => 60.0, Body::BipedSmall(biped_small) => match biped_small.species { biped_small::Species::Haniwa => 65.0, @@ -133,7 +133,7 @@ impl Body { Body::BirdMedium(_) => 6.0, Body::FishMedium(_) => 6.0, Body::Dragon(_) => 1.0, - Body::BirdSmall(_) => 7.0, + Body::BirdLarge(_) => 7.0, Body::FishSmall(_) => 7.0, Body::BipedLarge(_) => 1.6, Body::BipedSmall(_) => 2.4, @@ -165,7 +165,7 @@ impl Body { Body::BipedLarge(_) | Body::Golem(_) => Some(200.0 * self.mass().0), Body::BipedSmall(_) => Some(100.0 * self.mass().0), Body::BirdMedium(_) => Some(50.0 * self.mass().0), - Body::BirdSmall(_) => Some(50.0 * self.mass().0), + Body::BirdLarge(_) => Some(50.0 * self.mass().0), Body::FishMedium(_) => Some(50.0 * self.mass().0), Body::FishSmall(_) => Some(50.0 * self.mass().0), Body::Dragon(_) => Some(200.0 * self.mass().0), @@ -188,7 +188,7 @@ impl Body { pub fn fly_thrust(&self) -> Option { match self { Body::BirdMedium(_) => Some(GRAVITY * self.mass().0 * 2.0), - Body::BirdSmall(_) => Some(GRAVITY * self.mass().0 * 2.0), + Body::BirdLarge(_) => Some(GRAVITY * self.mass().0 * 0.5), Body::Dragon(_) => Some(200_000.0), Body::Ship(ship::Body::DefaultAirship) => Some(300_000.0), _ => None, @@ -377,7 +377,7 @@ pub fn fly_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) -> b // Elevation control match data.body { // flappy flappy - Body::Dragon(_) | Body::BirdMedium(_) | Body::BirdSmall(_) => { + Body::Dragon(_) | Body::BirdMedium(_) | Body::BirdLarge(_) => { let anti_grav = GRAVITY * (1.0 + data.inputs.move_z.min(0.0)); update.vel.0.z += data.dt.0 * (anti_grav + accel * data.inputs.move_z.max(0.0)); }, diff --git a/common/src/time.rs b/common/src/time.rs index 023c2f5089..a13ba253f4 100644 --- a/common/src/time.rs +++ b/common/src/time.rs @@ -1,4 +1,4 @@ -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum DayPeriod { Night, Morning, diff --git a/common/src/util/mod.rs b/common/src/util/mod.rs index 2dbbc44a4f..bfad8f01e9 100644 --- a/common/src/util/mod.rs +++ b/common/src/util/mod.rs @@ -4,6 +4,9 @@ pub mod find_dist; mod option; pub mod plane; pub mod projection; +/// Contains [`SpatialGrid`] which is useful for accelerating queries of nearby +/// entities +mod spatial_grid; pub const GIT_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/githash")); pub const GIT_TAG: &str = include_str!(concat!(env!("OUT_DIR"), "/gittag")); @@ -28,6 +31,7 @@ lazy_static::lazy_static! { pub use color::*; pub use dir::*; -pub use option::*; -pub use plane::*; -pub use projection::*; +pub use option::either_with; +pub use plane::Plane; +pub use projection::Projection; +pub use spatial_grid::SpatialGrid; diff --git a/common/sys/src/phys/spatial_grid.rs b/common/src/util/spatial_grid.rs similarity index 74% rename from common/sys/src/phys/spatial_grid.rs rename to common/src/util/spatial_grid.rs index 0e5cfd716a..aab6b67381 100644 --- a/common/sys/src/phys/spatial_grid.rs +++ b/common/src/util/spatial_grid.rs @@ -1,5 +1,6 @@ use vek::*; +#[derive(Debug)] pub struct SpatialGrid { // Uses two scales of grids so that we can have a hard limit on how far to search in the // smaller grid @@ -51,8 +52,6 @@ impl SpatialGrid { /// provided axis aligned bounding region /// NOTE: for best optimization of the iterator use `for_each` rather than a /// for loop - // TODO: a circle would be tighter (how efficient would it be to query the cells - // intersecting a circle?) pub fn in_aabr<'a>(&'a self, aabr: Aabr) -> impl Iterator + 'a { let iter = |max_entity_radius, grid: &'a hashbrown::HashMap<_, _>, lg2_cell_size| { // Add buffer for other entity radius @@ -74,4 +73,36 @@ impl SpatialGrid { self.lg2_large_cell_size, )) } + + /// Get an iterator over the entities overlapping the + /// axis aligned bounding region that contains the provided circle + /// NOTE: for best optimization of the iterator use `for_each` rather than a + /// for loop + // TODO: using the circle directly would be tighter (how efficient would it be + // to query the cells intersecting a circle?) (note: if doing this rename + // the function) + pub fn in_circle_aabr( + &self, + center: Vec2, + radius: f32, + ) -> impl Iterator + '_ { + let center = center.map(|e| e as i32); + let radius = radius.ceil() as i32; + // From conversion of center above + const CENTER_TRUNCATION_ERROR: i32 = 1; + let max_dist = radius + CENTER_TRUNCATION_ERROR; + + let aabr = Aabr { + min: center - max_dist, + max: center + max_dist, + }; + + self.in_aabr(aabr) + } + + pub fn clear(&mut self) { + self.grid.clear(); + self.large_grid.clear(); + self.largest_large_radius = self.radius_cutoff; + } } diff --git a/common/state/src/build_areas.rs b/common/state/src/build_areas.rs new file mode 100644 index 0000000000..8d1e273e77 --- /dev/null +++ b/common/state/src/build_areas.rs @@ -0,0 +1,54 @@ +use common::depot::{Depot, Id}; +use hashbrown::{hash_map, HashMap}; +use vek::*; + +/// NOTE: Please don't add `Deserialize` without checking to make sure we +/// can guarantee the invariant that every entry in `area_names` points to a +/// valid id in `areas`. +#[derive(Default)] +pub struct BuildAreas { + areas: Depot>, + area_names: HashMap>>, +} + +pub enum BuildAreaError { + /// This build area name is reserved by the system. + Reserved, + /// The build area name was not found. + NotFound, +} + +/// Build area names that can only be inserted, not removed. +const RESERVED_BUILD_AREA_NAMES: &[&str] = &["world"]; + +impl BuildAreas { + pub fn areas(&self) -> &Depot> { &self.areas } + + pub fn area_names(&self) -> &HashMap>> { &self.area_names } + + /// If the area_name is already in the map, returns Err(area_name). + pub fn insert(&mut self, area_name: String, area: Aabb) -> Result>, String> { + let area_name_entry = match self.area_names.entry(area_name) { + hash_map::Entry::Occupied(o) => return Err(o.replace_key()), + hash_map::Entry::Vacant(v) => v, + }; + let bb_id = self.areas.insert(area.made_valid()); + area_name_entry.insert(bb_id); + Ok(bb_id) + } + + pub fn remove(&mut self, area_name: &str) -> Result, BuildAreaError> { + if RESERVED_BUILD_AREA_NAMES.contains(&area_name) { + return Err(BuildAreaError::Reserved); + } + let bb_id = self + .area_names + .remove(area_name) + .ok_or(BuildAreaError::NotFound)?; + let area = self.areas.remove(bb_id).expect( + "Entries in `areas` are added before entries in `area_names` in `insert`, and that is \ + the only exposed way to add elements to `area_names`.", + ); + Ok(area) + } +} diff --git a/common/state/src/lib.rs b/common/state/src/lib.rs index c633e60771..d0047fe6de 100644 --- a/common/state/src/lib.rs +++ b/common/state/src/lib.rs @@ -1,589 +1,9 @@ +//! This crate contains the [`State`] and shared between +//! server (`veloren-server`) and the client (`veloren-client`) + +mod build_areas; #[cfg(feature = "plugins")] pub mod plugin; - -#[cfg(feature = "plugins")] -use crate::plugin::memory_manager::EcsWorld; -#[cfg(feature = "plugins")] -use crate::plugin::PluginMgr; -#[cfg(feature = "plugins")] -use common::uid::UidAllocator; -use common::{ - comp, - depot::{Depot, Id}, - event::{EventBus, LocalEvent, ServerEvent}, - outcome::Outcome, - region::RegionMap, - resources::{DeltaTime, GameMode, PlayerEntity, PlayerPhysicsSettings, Time, TimeOfDay}, - slowjob::SlowJobPool, - terrain::{Block, TerrainChunk, TerrainGrid}, - time::DayPeriod, - trade::Trades, - vol::{ReadVol, WriteVol}, -}; -use common_base::span; -use common_ecs::{PhysicsMetrics, SysMetrics}; -use common_net::sync::{interpolation as sync_interp, WorldSyncExt}; -use core::{convert::identity, time::Duration}; -use hashbrown::{hash_map, HashMap, HashSet}; -use rayon::{ThreadPool, ThreadPoolBuilder}; -use specs::{ - prelude::Resource, - shred::{Fetch, FetchMut}, - storage::{MaskedStorage as EcsMaskedStorage, Storage as EcsStorage}, - Component, DispatcherBuilder, Entity as EcsEntity, WorldExt, -}; -use std::sync::Arc; -use vek::*; - -/// How much faster should an in-game day be compared to a real day? -// TODO: Don't hard-code this. -const DAY_CYCLE_FACTOR: f64 = 24.0 * 2.0; - -/// At what point should we stop speeding up physics to compensate for lag? If -/// we speed physics up too fast, we'd skip important physics events like -/// collisions. This constant determines the upper limit. If delta time exceeds -/// this value, the game's physics will begin to produce time lag. Ideally, we'd -/// avoid such a situation. -const MAX_DELTA_TIME: f32 = 1.0; - -/// NOTE: Please don't add `Deserialize` without checking to make sure we -/// can guarantee the invariant that every entry in `area_names` points to a -/// valid id in `areas`. -#[derive(Default)] -pub struct BuildAreas { - areas: Depot>, - area_names: HashMap>>, -} - -pub enum BuildAreaError { - /// This build area name is reserved by the system. - Reserved, - /// The build area name was not found. - NotFound, -} - -/// Build area names that can only be inserted, not removed. -const RESERVED_BUILD_AREA_NAMES: &[&str] = &["world"]; - -impl BuildAreas { - pub fn areas(&self) -> &Depot> { &self.areas } - - pub fn area_names(&self) -> &HashMap>> { &self.area_names } - - /// If the area_name is already in the map, returns Err(area_name). - pub fn insert(&mut self, area_name: String, area: Aabb) -> Result>, String> { - let area_name_entry = match self.area_names.entry(area_name) { - hash_map::Entry::Occupied(o) => return Err(o.replace_key()), - hash_map::Entry::Vacant(v) => v, - }; - let bb_id = self.areas.insert(area.made_valid()); - area_name_entry.insert(bb_id); - Ok(bb_id) - } - - pub fn remove(&mut self, area_name: &str) -> Result, BuildAreaError> { - if RESERVED_BUILD_AREA_NAMES.contains(&area_name) { - return Err(BuildAreaError::Reserved); - } - let bb_id = self - .area_names - .remove(area_name) - .ok_or(BuildAreaError::NotFound)?; - let area = self.areas.remove(bb_id).expect( - "Entries in `areas` are added before entries in `area_names` in `insert`, and that is \ - the only exposed way to add elements to `area_names`.", - ); - Ok(area) - } -} - -#[derive(Default)] -pub struct BlockChange { - blocks: HashMap, Block>, -} - -impl BlockChange { - pub fn set(&mut self, pos: Vec3, block: Block) { self.blocks.insert(pos, block); } - - pub fn try_set(&mut self, pos: Vec3, block: Block) -> Option<()> { - if !self.blocks.contains_key(&pos) { - self.blocks.insert(pos, block); - Some(()) - } else { - None - } - } - - pub fn clear(&mut self) { self.blocks.clear(); } -} - -#[derive(Default)] -pub struct TerrainChanges { - pub new_chunks: HashSet>, - pub modified_chunks: HashSet>, - pub removed_chunks: HashSet>, - pub modified_blocks: HashMap, Block>, -} - -impl TerrainChanges { - pub fn clear(&mut self) { - self.new_chunks.clear(); - self.modified_chunks.clear(); - self.removed_chunks.clear(); - } -} - -#[derive(Copy, Clone)] -pub enum ExecMode { - Server, - Client, - Singleplayer, -} - -/// A type used to represent game state stored on both the client and the -/// server. This includes things like entity components, terrain data, and -/// global states like weather, time of day, etc. -pub struct State { - ecs: specs::World, - // Avoid lifetime annotation by storing a thread pool instead of the whole dispatcher - thread_pool: Arc, -} - -impl State { - /// Create a new `State` in client mode. - pub fn client() -> Self { Self::new(GameMode::Client) } - - /// Create a new `State` in server mode. - pub fn server() -> Self { Self::new(GameMode::Server) } - - pub fn new(game_mode: GameMode) -> Self { - let thread_name_infix = match game_mode { - GameMode::Server => "s", - GameMode::Client => "c", - GameMode::Singleplayer => "sp", - }; - - let thread_pool = Arc::new( - ThreadPoolBuilder::new() - .thread_name(move |i| format!("rayon-{}-{}", thread_name_infix, i)) - .build() - .unwrap(), - ); - Self { - ecs: Self::setup_ecs_world(game_mode, &thread_pool), - thread_pool, - } - } - - /// Creates ecs world and registers all the common components and resources - // TODO: Split up registering into server and client (e.g. move - // EventBus to the server) - fn setup_ecs_world(game_mode: GameMode, thread_pool: &Arc) -> specs::World { - let mut ecs = specs::World::new(); - // Uids for sync - ecs.register_sync_marker(); - // Register server -> all clients synced components. - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - - // Register components send from clients -> server - ecs.register::(); - - // Register components send directly from server -> all but one client - ecs.register::(); - - // Register components synced from client -> server -> all other clients - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - - // Register common unsynced components - ecs.register::(); - ecs.register::(); - - // Register client-local components - // TODO: only register on the client - ecs.register::(); - ecs.register::>(); - ecs.register::>(); - ecs.register::>(); - - // Register server-local components - // TODO: only register on the server - ecs.register::>(); - ecs.register::>(); - ecs.register::>(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - ecs.register::(); - - // Register synced resources used by the ECS. - ecs.insert(TimeOfDay(0.0)); - - // Register unsynced resources used by the ECS. - ecs.insert(Time(0.0)); - ecs.insert(DeltaTime(0.0)); - ecs.insert(PlayerEntity(None)); - ecs.insert(TerrainGrid::new().unwrap()); - ecs.insert(BlockChange::default()); - ecs.insert(BuildAreas::default()); - ecs.insert(TerrainChanges::default()); - ecs.insert(EventBus::::default()); - ecs.insert(game_mode); - ecs.insert(Vec::::new()); - - let slow_limit = thread_pool.current_num_threads().max(2) as u64; - let slow_limit = slow_limit / 2 + slow_limit / 4; - tracing::trace!(?slow_limit, "Slow Thread limit"); - ecs.insert(SlowJobPool::new(slow_limit, Arc::clone(&thread_pool))); - - // TODO: only register on the server - ecs.insert(EventBus::::default()); - ecs.insert(comp::group::GroupManager::default()); - ecs.insert(RegionMap::new()); - ecs.insert(SysMetrics::default()); - ecs.insert(PhysicsMetrics::default()); - ecs.insert(Trades::default()); - ecs.insert(PlayerPhysicsSettings::default()); - - // Load plugins from asset directory - #[cfg(feature = "plugins")] - ecs.insert(match PluginMgr::from_assets() { - Ok(plugin_mgr) => { - let ecs_world = EcsWorld { - entities: &ecs.entities(), - health: ecs.read_component().into(), - uid: ecs.read_component().into(), - uid_allocator: &ecs.read_resource::().into(), - player: ecs.read_component().into(), - }; - if let Err(e) = plugin_mgr - .execute_event(&ecs_world, &plugin_api::event::PluginLoadEvent { - game_mode, - }) - { - tracing::debug!(?e, "Failed to run plugin init"); - tracing::info!("Plugins disabled, enable debug logging for more information."); - PluginMgr::default() - } else { - plugin_mgr - } - }, - Err(e) => { - tracing::debug!(?e, "Failed to read plugins from assets"); - tracing::info!("Plugins disabled, enable debug logging for more information."); - PluginMgr::default() - }, - }); - - ecs - } - - /// Register a component with the state's ECS. - pub fn with_component(mut self) -> Self - where - ::Storage: Default, - { - self.ecs.register::(); - self - } - - /// Write a component attributed to a particular entity, ignoring errors. - /// - /// This should be used *only* when we can guarantee that the rest of the - /// code does not rely on the insert having succeeded (meaning the - /// entity is no longer alive!). - /// - /// Returns None if the entity was dead or there was no previous entry for - /// this component; otherwise, returns Some(old_component). - pub fn write_component_ignore_entity_dead( - &mut self, - entity: EcsEntity, - comp: C, - ) -> Option { - self.ecs - .write_storage() - .insert(entity, comp) - .ok() - .and_then(identity) - } - - /// Delete a component attributed to a particular entity. - pub fn delete_component(&mut self, entity: EcsEntity) -> Option { - self.ecs.write_storage().remove(entity) - } - - /// Read a component attributed to a particular entity. - pub fn read_component_cloned(&self, entity: EcsEntity) -> Option { - self.ecs.read_storage().get(entity).cloned() - } - - /// Read a component attributed to a particular entity. - pub fn read_component_copied(&self, entity: EcsEntity) -> Option { - self.ecs.read_storage().get(entity).copied() - } - - /// Given mutable access to the resource R, assuming the resource - /// component exists (this is already the behavior of functions like `fetch` - /// and `write_component_ignore_entity_dead`). Since all of our resources - /// are generated up front, any failure here is definitely a code bug. - pub fn mut_resource(&mut self) -> &mut R { - self.ecs.get_mut::().expect( - "Tried to fetch an invalid resource even though all our resources should be known at \ - compile time.", - ) - } - - /// Get a read-only reference to the storage of a particular component type. - pub fn read_storage(&self) -> EcsStorage>> { - self.ecs.read_storage::() - } - - /// Get a reference to the internal ECS world. - pub fn ecs(&self) -> &specs::World { &self.ecs } - - /// Get a mutable reference to the internal ECS world. - pub fn ecs_mut(&mut self) -> &mut specs::World { &mut self.ecs } - - /// Get a reference to the `TerrainChanges` structure of the state. This - /// contains information about terrain state that has changed since the - /// last game tick. - pub fn terrain_changes(&self) -> Fetch { self.ecs.read_resource() } - - /// Get the current in-game time of day. - /// - /// Note that this should not be used for physics, animations or other such - /// localised timings. - pub fn get_time_of_day(&self) -> f64 { self.ecs.read_resource::().0 } - - /// Get the current in-game day period (period of the day/night cycle) - /// Get the current in-game day period (period of the day/night cycle) - pub fn get_day_period(&self) -> DayPeriod { self.get_time_of_day().into() } - - /// Get the current in-game time. - /// - /// Note that this does not correspond to the time of day. - pub fn get_time(&self) -> f64 { self.ecs.read_resource::