From 2d793d7e657b6d716191414859cc1e16310084f4 Mon Sep 17 00:00:00 2001 From: Monty Marz Date: Tue, 11 Aug 2020 16:05:34 +0200 Subject: [PATCH] Add firework hues --- CHANGELOG.md | 1 + assets/common/items/utility/firework.ron | 7 --- assets/common/items/utility/firework_blue.ron | 7 +++ .../common/items/utility/firework_green.ron | 7 +++ .../common/items/utility/firework_purple.ron | 7 +++ assets/common/items/utility/firework_red.ron | 7 +++ .../common/items/utility/firework_yellow.ron | 7 +++ assets/common/loot_table.ron | 1 - assets/common/recipe_book.ron | 6 ++- assets/voxygen/item_image_manifest.ron | 20 ++++++- assets/voxygen/shaders/particle-vert.glsl | 51 ++++++++++++++++++ .../voxel/weapon/projectile/fireworks-0.vox | Bin 0 -> 1260 bytes .../weapon/projectile/fireworks_blue-0.vox | Bin 0 -> 1260 bytes .../weapon/projectile/fireworks_green-0.vox | Bin 0 -> 1260 bytes .../weapon/projectile/fireworks_purple-0.vox | Bin 0 -> 1260 bytes .../weapon/projectile/fireworks_red-0.vox | Bin 0 -> 1260 bytes .../weapon/projectile/fireworks_yellow-0.vox | Bin 0 -> 1260 bytes common/src/comp/body/object.rs | 20 +++++-- common/src/comp/inventory/item/mod.rs | 11 +++- common/src/comp/misc.rs | 10 +++- common/src/event.rs | 3 +- common/src/outcome.rs | 2 + common/src/sys/projectile.rs | 2 + server/src/cmd.rs | 1 + server/src/events/entity_manipulation.rs | 8 ++- server/src/events/inventory_manip.rs | 33 ++++++++++-- server/src/events/mod.rs | 3 +- server/src/sys/object.rs | 16 ++++-- voxygen/src/audio/sfx/mod.rs | 2 +- voxygen/src/lib.rs | 2 +- voxygen/src/render/pipelines/particle.rs | 5 ++ voxygen/src/scene/figure/load.rs | 21 +++++++- voxygen/src/scene/mod.rs | 29 ++++++++-- voxygen/src/scene/particle.rs | 29 ++++++++-- 34 files changed, 277 insertions(+), 41 deletions(-) delete mode 100644 assets/common/items/utility/firework.ron create mode 100644 assets/common/items/utility/firework_blue.ron create mode 100644 assets/common/items/utility/firework_green.ron create mode 100644 assets/common/items/utility/firework_purple.ron create mode 100644 assets/common/items/utility/firework_red.ron create mode 100644 assets/common/items/utility/firework_yellow.ron create mode 100644 assets/voxygen/voxel/weapon/projectile/fireworks-0.vox create mode 100644 assets/voxygen/voxel/weapon/projectile/fireworks_blue-0.vox create mode 100644 assets/voxygen/voxel/weapon/projectile/fireworks_green-0.vox create mode 100644 assets/voxygen/voxel/weapon/projectile/fireworks_purple-0.vox create mode 100644 assets/voxygen/voxel/weapon/projectile/fireworks_red-0.vox create mode 100644 assets/voxygen/voxel/weapon/projectile/fireworks_yellow-0.vox diff --git a/CHANGELOG.md b/CHANGELOG.md index 06d7096ee9..2f9506382a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add detection of entities under the cursor - Functional group-system with exp-sharing and disabled damage to group members - Some Campfire, fireball & bomb; particle, light & sound effects. +- Added firework recipe - Added setting to change resolution ### Changed diff --git a/assets/common/items/utility/firework.ron b/assets/common/items/utility/firework.ron deleted file mode 100644 index a33bf47fae..0000000000 --- a/assets/common/items/utility/firework.ron +++ /dev/null @@ -1,7 +0,0 @@ -Item( - name: "Firework", - description: "Label: Outdoor use only!\n\n", - kind: Throwable( - kind: Firework, - ), -) diff --git a/assets/common/items/utility/firework_blue.ron b/assets/common/items/utility/firework_blue.ron new file mode 100644 index 0000000000..5468670824 --- /dev/null +++ b/assets/common/items/utility/firework_blue.ron @@ -0,0 +1,7 @@ +Item( + name: "Firework Blue", + description: "Recommended clearance: 42 chonks\n\n", + kind: Throwable( + kind: Firework(Blue), + ), +) diff --git a/assets/common/items/utility/firework_green.ron b/assets/common/items/utility/firework_green.ron new file mode 100644 index 0000000000..ae329c12da --- /dev/null +++ b/assets/common/items/utility/firework_green.ron @@ -0,0 +1,7 @@ +Item( + name: "Firework Green", + description: "Watch out for trees.\n\n", + kind: Throwable( + kind: Firework(Green), + ), +) diff --git a/assets/common/items/utility/firework_purple.ron b/assets/common/items/utility/firework_purple.ron new file mode 100644 index 0000000000..e217d72ff7 --- /dev/null +++ b/assets/common/items/utility/firework_purple.ron @@ -0,0 +1,7 @@ +Item( + name: "Firework Purple", + description: "Cult favourite.\n\n", + kind: Throwable( + kind: Firework(Purple), + ), +) diff --git a/assets/common/items/utility/firework_red.ron b/assets/common/items/utility/firework_red.ron new file mode 100644 index 0000000000..edda2afe76 --- /dev/null +++ b/assets/common/items/utility/firework_red.ron @@ -0,0 +1,7 @@ +Item( + name: "Firework Red", + description: "Humans sometimes use these\nas a flare in a pinch.\n\n", + kind: Throwable( + kind: Firework(Red), + ), +) diff --git a/assets/common/items/utility/firework_yellow.ron b/assets/common/items/utility/firework_yellow.ron new file mode 100644 index 0000000000..652408f515 --- /dev/null +++ b/assets/common/items/utility/firework_yellow.ron @@ -0,0 +1,7 @@ +Item( + name: "Firework Yellow", + description: "The Great Dr. passed away after\ntesting this contraption indoors.\n\n", + kind: Throwable( + kind: Firework(Yellow), + ), +) diff --git a/assets/common/loot_table.ron b/assets/common/loot_table.ron index f39443ba4a..4d0a7e98bf 100644 --- a/assets/common/loot_table.ron +++ b/assets/common/loot_table.ron @@ -9,7 +9,6 @@ (0.4, "common.items.ore.velorite"), (0.6, "common.items.ore.veloritefrag"), (0.1, "common.items.consumable.potion_minor"), - (1.0, "common.items.utility.firework"), (0.01, "common.items.utility.collar"), (0.01, "common.items.utility.bomb_pile"), (0.1, "common.items.utility.bomb"), diff --git a/assets/common/recipe_book.ron b/assets/common/recipe_book.ron index 0637d439fc..7e4d6b66d1 100644 --- a/assets/common/recipe_book.ron +++ b/assets/common/recipe_book.ron @@ -6,7 +6,11 @@ "potion_m": (("common.items.consumable.potion_med", 1), [("common.items.consumable.potion_minor", 2), ("common.items.ore.veloritefrag", 4)]), "collar_basic": (("common.items.utility.collar", 1), [("common.items.crafting_ing.leather_scraps", 5), ("common.items.crafting_ing.shiny_gem", 1)]), "bomb_coconut": (("common.items.utility.bomb", 1), [("common.items.crafting_ing.stones", 10), ("common.items.food.coconut", 2), ("common.items.ore.veloritefrag", 2), ("common.items.crafting_tools.mortar_pestle", 0)]), - "firework": (("common.items.utility.firework", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 2), ("common.items.ore.veloritefrag", 10), ("common.items.crafting_tools.mortar_pestle", 0)]), + "firework_blue": (("common.items.utility.firework_blue", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]), + "firework_green": (("common.items.utility.firework_green", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]), + "firework_purple": (("common.items.utility.firework_purple", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]), + "firework_red": (("common.items.utility.firework_red", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]), + "firework_yellow": (("common.items.utility.firework_yellow", 1), [("common.items.crafting_ing.twigs", 1), ("common.items.crafting_ing.stones", 1), ("common.items.food.coconut", 1), ("common.items.ore.veloritefrag", 1), ("common.items.crafting_tools.mortar_pestle", 0)]), "apple_shroom_curry": (("common.items.food.apple_mushroom_curry", 1), [("common.items.food.mushroom", 10), ("common.items.food.coconut", 1), ("common.items.food.apple", 5), ("common.items.crafting_tools.mortar_pestle", 0)]), "apples_stick": (("common.items.food.apple_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.apple", 3)]), "mushroom_stick": (("common.items.food.mushroom_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.mushroom", 5)]), diff --git a/assets/voxygen/item_image_manifest.ron b/assets/voxygen/item_image_manifest.ron index 3101fd660d..7bfa8a6c2f 100644 --- a/assets/voxygen/item_image_manifest.ron +++ b/assets/voxygen/item_image_manifest.ron @@ -1110,8 +1110,24 @@ "voxel.object.bomb", (0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8, ), - Throwable(Firework): VoxTrans( - "voxel.object.firework", + Throwable(Firework(Blue)): VoxTrans( + "voxel.weapon.projectile.fireworks_blue-0", + (0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8, + ), + Throwable(Firework(Green)): VoxTrans( + "voxel.weapon.projectile.fireworks_green-0", + (0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8, + ), + Throwable(Firework(Purple)): VoxTrans( + "voxel.weapon.projectile.fireworks_purple-0", + (0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8, + ), + Throwable(Firework(Red)): VoxTrans( + "voxel.weapon.projectile.fireworks_red-0", + (0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8, + ), + Throwable(Firework(Yellow)): VoxTrans( + "voxel.weapon.projectile.fireworks_yellow-0", (0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8, ), Throwable(TrainingDummy): VoxTrans( diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 2f2914f63d..10fd626140 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -26,6 +26,12 @@ const int FIRE = 1; const int GUN_POWDER_SPARK = 2; const int SHRAPNEL = 3; +const int FIREWORK_BLUE = 4; +const int FIREWORK_GREEN = 5; +const int FIREWORK_PURPLE = 6; +const int FIREWORK_RED = 7; +const int FIREWORK_YELLOW = 8; + // meters per second squared (acceleration) const float earth_gravity = 9.807; @@ -97,6 +103,51 @@ void main() { 3.0 + rand0, vec3(0.6 + rand7 * 0.4) ); + } else if (inst_mode == FIREWORK_BLUE) { + attr = Attr( + linear_motion( + vec3(0.0, 1.0, 1.0), + vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity) + ), + 3.0 + rand0, + vec3(0.6 + rand7 * 0.4) + ); + } else if (inst_mode == FIREWORK_GREEN) { + attr = Attr( + linear_motion( + vec3(0.0, 1.0, 0.0), + vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity) + ), + 3.0 + rand0, + vec3(0.6 + rand7 * 0.4) + ); + } else if (inst_mode == FIREWORK_PURPLE) { + attr = Attr( + linear_motion( + vec3(1.0, 0.0, 1.0), + vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity) + ), + 3.0 + rand0, + vec3(0.6 + rand7 * 0.4) + ); + } else if (inst_mode == FIREWORK_RED) { + attr = Attr( + linear_motion( + vec3(1.0, 0.0, 0.0), + vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity) + ), + 3.0 + rand0, + vec3(0.6 + rand7 * 0.4) + ); + } else if (inst_mode == FIREWORK_YELLOW) { + attr = Attr( + linear_motion( + vec3(1.0, 1.0, 0.0), + vec3(rand4, rand5, rand6) * 40.0 + grav_vel(earth_gravity) + ), + 3.0 + rand0, + vec3(0.6 + rand7 * 0.4) + ); } else { attr = Attr( linear_motion( diff --git a/assets/voxygen/voxel/weapon/projectile/fireworks-0.vox b/assets/voxygen/voxel/weapon/projectile/fireworks-0.vox new file mode 100644 index 0000000000000000000000000000000000000000..4558233284f613a88df1b94c0cde7e3a0c014390 GIT binary patch literal 1260 zcmeH`-)mA~7{{M;wsVfobr}rTa2N9;4Gf2s5~wwoI!xU(=dpB*IhY9w8l)Gw3)#Q~ zFLI-VI3O;THxk$nx~Z#f8mt?k`|kQDzCDNfCk8$6;q$!jd7hW&ec?QaZY~}ZQN$m* z&!V5xL>nPBFsm;(rkG3r*i5UTQ+<=;DkCVgC@6wOP(=0=dzvj-1WC@4EN2B-PKde{ zMp68F-JaFp`n$j9h07inc zpJn2+O#F?l==p4R{oWlv@tyQAo6WFTEU;Rwu-R;II2>@fT<~~2@Or%n1Of<$!-z(s zNG6j|RTa5h4m&$LC=?1Pl}e~qtEkuOXfzsVHk)X*TIh5-=ytp4^?J}W4THe|!{HF4 z(Fo)57-{zv6vH+o?S!rCgo2Ck#6#Hk5n2JlQJA2`2*V`dy-M&o?O46xK*Y0*4ew2) zS8ih~=)-Pg1;zCsDyax+nK<^hk~qkx(Jo~1qO^@y)m^-<7t!CZ;LSk|UycZq6TYr)ehl3JVu~f6uQd-oL@-(|w{qiFg|+lQBPbNIBdfM1ym%#JvgANEn| n{=j@}9xly=@_89rg8Rzc_niCw$Ax);v$L}cGpjzR{{R00C3#YK literal 0 HcmV?d00001 diff --git a/assets/voxygen/voxel/weapon/projectile/fireworks_blue-0.vox b/assets/voxygen/voxel/weapon/projectile/fireworks_blue-0.vox new file mode 100644 index 0000000000000000000000000000000000000000..c1b7ded44799ba7802344d8943a25145cab235bd GIT binary patch literal 1260 zcmeH`(Q8t16vxlK+r3xkdJMuv?qNQp3&U}1N}$$U&SAPub6!iw*an)Qph5bOK8y`a z@F6!!hzrAF`67W8^iVzZlCWNc-h1nx_;xP!PYgQn;d6e!d(MyZ`@y{*-JCrpqDWxn z9*cfX5^bz#!D(Z`F~MB;$7V`fIW;ypt}=o`vw|Yn1Vv;|uqWA)O_1aa$#O=J<+x~A zVI(C^vJw{<(XhfuCayDaor(9@3L}}h&dhb@kZ4%pwKVlmU_^#w&gH2kkxdHcjA&T0 z@L3i<%fjE-ijhxe*6-d95Z}oNtJMmd%?7*O4u``5m&*lJRpIq|;q&q88E+1%_;N%Tzb5?t zK)^TV`$gc)35@-iTb_e6?u2{W4Nu8~z|#Oitq@|}7?P(+><)HO{#b_X&MNF{8s@V( zxF0>iV)YQd!(+_nu3`0L2<`1Bcd;tO0^{)}JgG_0;QEIc?t nvGW5nu^FhkiqcsLdYt=8-1m(8{>Qm_fzfDmZe}$GHU9rU^ZQZ^ literal 0 HcmV?d00001 diff --git a/assets/voxygen/voxel/weapon/projectile/fireworks_green-0.vox b/assets/voxygen/voxel/weapon/projectile/fireworks_green-0.vox new file mode 100644 index 0000000000000000000000000000000000000000..072499b66c961ffe41b15bcd4c67e0f13e54d606 GIT binary patch literal 1260 zcmeH`O=}ua6o$`CGBX;}Wg(abvxtyt!D6tjQcznbH3qBsm>MUgN;(E&1qCfs7uAI% zU;|mygjOg*NJ{EP3ig9;+Eq6dl1-rd?)oR*o}v8{fgX5x&b@Qa<=hMNAh9-mKt%EI z!hII~93@&=(A9Bs!7;*I`o~&YUpO&0Ij%B-LeqjGI0QvxkFZDCl0%SWgJjtdWLXzY zD~zP*BrCeWh^7@rvT&V+>nyy-Rv5|3bylvkMn%&Kucfia0wXdcb1siXL^dg$Gooq9 z#%J01EE|7gD`q}!EZ@5mCccvycDo%8hXYQh6E2qv9*+k;pAUgR0Ks4os;VLuiy@In zK+`nnx{gdH1H&+o&*xDr7E!5GP^;BYuh-FRHqmOeu(!8|cDs#Er-N>{i=(3>^m;w? z`+W=s1El>|P>8vpxe3|pguIXNG(c#C2rZScA0u>=gq}wDpc6t~H|B465D&~@C3q9* z$Zce!A#BDYC@e=&PQ_7OUqU0RVLO+`ZvGKo7B}#^vWYjf0uCExyxp$i>ptQ9nDF}} z0pFP)mw{6^a2~?U{0!WyZg@Am@R$4uKMy0i8%45{MCv4kTtA2Mr!pLO7vWseaV@h2 z?~`Y^Roy{w=KyN^7>kDk=-{%$`7Y-?KMJDr3 zV$sDk(P~6f=Zpo%6m#VtYgsLFVr+8UU<8F01Vyk4ipZW~PqQVfAjx@><-8!vDbcXP zNJ@%iB_%MTVTF-QTxa4s6YsGVMw;Qe8LpcNi-r|mOS4Y}Mr26lT%HYzY*IL9M8lGq z&oc8_X8y)jjC?M?^6-9u_)bPxEEZU;R@iJd*zI;WoldyjZg{<3_##mphApY#W?>7i z?dQ1L+=XxV5XWi=%fkt@_g}E};Tv?m%Q?@Fiuo^ler#WRjmG>5e&uqoIFndnPBFsm;(rkG3r*i5UTQ+<=;DkCVgC@6wOP(=0=dzvj-1WC@4EN2B-PKde{ zMp68F-JaFp`n$j9h07inc zpJn2+O#F?l==p4R{oWlv@tyQAo6WFTEU;Rwu-R;II2>@fT<~~2@Or%n1Of<$!-z(s zNG6j|RTa5h4m&$LC=?1Pl}e~qtEkuOXfzsVHk)X*TIh5-=ytp4^?J}W4THe|!{HF4 z(Fo)57-{zv6vH+o?S!rCgo2Ck#6#Hk5n2JlQJA2`2*V`dy-M&o?O46xK*Y0*4ew2) zS8ih~=)-Pg1;zCsDyax+nK<^hk~qkx(Jo~1qO^@y)m^-<7t!CZ;LSk|UycZq6TYr)ehl3JVu~f6uQd-oL@-(|w{qiFg|+lQBPbNIBdfM1ym%#JvgANEn| n{=j@}9xly=@_89rg8Rzc_niCw$Ax);v$L}cGpjzR{{R00C3#YK literal 0 HcmV?d00001 diff --git a/assets/voxygen/voxel/weapon/projectile/fireworks_yellow-0.vox b/assets/voxygen/voxel/weapon/projectile/fireworks_yellow-0.vox new file mode 100644 index 0000000000000000000000000000000000000000..89509cb5df57dee0dd21b6e27787b960fdbb0097 GIT binary patch literal 1260 zcmeH`O=}ua6o$`CGBYuz%Wh1;EaIY?VlhlxrJxo~)#67!rpB>V2^!D}3R-Af)GR^* zR&Y@hs89wZEvXwR*cQ5JSKTy_ZUWtRmp}3LOxr&Z=z)jl%$;-YJ$GOpCN~$3h$tS6 zCRp@ynrJ<$hv&=(jw$BKKQ=RZ^u%1`xXuU)EeMKW7Zi~_#hzwMc0rPJB+EHLmJ_0B zg^`p5$x1?CMAHf*&2Zfe*Uj)6TVW&%*IBsE5)n-+mJCU=j|E0#NakFg4T)@0IA=uD zl9l(e@?KVc$5zaIF1L37UXb`sX4q^t*zI;W91b|0PPpA}sHzH|&j-KXk8n7QSS*HQ zG6_x7pzAvF`82%QR_0aG4F&GSB7zU1yk1-mJ zFdmOFnM{!JUPCqJgytd?ZW1ag;i-?X8z6MTgu@uYND)RF;e$>HcwAVynos=1BVtty7Q4ZPjo!IwkA`5VH; zM*_Yv->(8^F5o;J%f kY96YgqJCC~vB7 for super::Body { @@ -187,7 +195,11 @@ impl Body { Body::BoltFireBig => "bolt_fire_big", Body::ArrowSnake => "arrow_snake", Body::TrainingDummy => "training_dummy", - Body::Firework => "firework", + Body::FireworkBlue => "firework_blue", + Body::FireworkGreen => "firework_green", + Body::FireworkPurple => "firework_purple", + Body::FireworkRed => "firework_red", + Body::FireworkYellow => "firework_yellow", } } } diff --git a/common/src/comp/inventory/item/mod.rs b/common/src/comp/inventory/item/mod.rs index b847361a60..7f1fbe8d61 100644 --- a/common/src/comp/inventory/item/mod.rs +++ b/common/src/comp/inventory/item/mod.rs @@ -20,7 +20,16 @@ use vek::Rgb; pub enum Throwable { Bomb, TrainingDummy, - Firework, + Firework(Reagent), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Reagent { + Blue, + Green, + Purple, + Red, + Yellow, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/common/src/comp/misc.rs b/common/src/comp/misc.rs index e926d693c3..70bd4748c4 100644 --- a/common/src/comp/misc.rs +++ b/common/src/comp/misc.rs @@ -1,3 +1,4 @@ +use super::item::Reagent; use crate::sync::Uid; use serde::{Deserialize, Serialize}; use specs::Component; @@ -5,8 +6,13 @@ use specs_idvs::IdvStorage; #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum Object { - Bomb { owner: Option }, - Firework { owner: Option }, + Bomb { + owner: Option, + }, + Firework { + owner: Option, + reagent: Reagent, + }, } impl Component for Object { diff --git a/common/src/event.rs b/common/src/event.rs index 943757a2a7..671af425a6 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -1,5 +1,5 @@ use crate::{comp, sync::Uid, util::Dir}; -use comp::item::Item; +use comp::item::{Item, Reagent}; use parking_lot::Mutex; use specs::Entity as EcsEntity; use std::{collections::VecDeque, ops::DerefMut}; @@ -26,6 +26,7 @@ pub enum ServerEvent { power: f32, owner: Option, friendly_damage: bool, + reagent: Option, }, Damage { uid: Uid, diff --git a/common/src/outcome.rs b/common/src/outcome.rs index 4f89f418b0..6088e99959 100644 --- a/common/src/outcome.rs +++ b/common/src/outcome.rs @@ -1,4 +1,5 @@ use crate::comp; +use comp::item::Reagent; use serde::{Deserialize, Serialize}; use vek::*; @@ -12,6 +13,7 @@ pub enum Outcome { Explosion { pos: Vec3, power: f32, + reagent: Option, // How can we better define this? }, ProjectileShot { pos: Vec3, diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index 20f96fc311..439f038a95 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -71,6 +71,7 @@ impl<'a> System<'a> for Sys { power, owner: projectile.owner, friendly_damage: false, + reagent: None, }) }, projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { @@ -133,6 +134,7 @@ impl<'a> System<'a> for Sys { power, owner: projectile.owner, friendly_damage: false, + reagent: None, }) }, projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 5a282766fd..8f828673cf 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1039,6 +1039,7 @@ fn handle_explosion( power, owner: ecs.read_storage::().get(target).copied(), friendly_damage: true, + reagent: None, }) }, None => server.notify_client( diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index ff6f4ae2b6..4a8cfe12d2 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -13,6 +13,7 @@ use common::{ terrain::{Block, TerrainGrid}, vol::{ReadVol, Vox}, }; +use comp::item::Reagent; use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt}; use tracing::error; use vek::Vec3; @@ -284,6 +285,7 @@ pub fn handle_explosion( power: f32, owner: Option, friendly_damage: bool, + reagent: Option, ) { // Go through all other entities let hit_range = 3.0 * power; @@ -291,7 +293,11 @@ pub fn handle_explosion( // Add an outcome ecs.write_resource::>() - .push(Outcome::Explosion { pos, power }); + .push(Outcome::Explosion { + pos, + power, + reagent, + }); let owner_entity = owner.and_then(|uid| { ecs.read_resource::() diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs index b8d5d1a01e..31dbe26b35 100644 --- a/server/src/events/inventory_manip.rs +++ b/server/src/events/inventory_manip.rs @@ -11,10 +11,11 @@ use common::{ terrain::block::Block, vol::{ReadVol, Vox}, }; +use comp::LightEmitter; use rand::Rng; use specs::{join::Join, world::WorldExt, Builder, Entity as EcsEntity, WriteStorage}; use tracing::{debug, error}; -use vek::Vec3; +use vek::{Rgb, Vec3}; pub fn swap_lantern( storage: &mut WriteStorage, @@ -400,10 +401,16 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv .build(); } + let mut rng = rand::thread_rng(); + // Throw items for (pos, vel, ori, kind) in thrown_items { let vel = match kind { - item::Throwable::Firework => Vec3::unit_z() * 200.0, + item::Throwable::Firework(_) => Vec3::new( + rng.gen_range(-15.0, 15.0), + rng.gen_range(-15.0, 15.0), + rng.gen_range(80.0, 110.0), + ), _ => { vel.0 + *ori.0 * 20.0 @@ -417,7 +424,13 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv let mut new_entity = state .create_object(Default::default(), match kind { item::Throwable::Bomb => comp::object::Body::Bomb, - item::Throwable::Firework => comp::object::Body::Bomb, + item::Throwable::Firework(reagent) => match reagent { + item::Reagent::Blue => comp::object::Body::FireworkBlue, + item::Reagent::Green => comp::object::Body::FireworkGreen, + item::Reagent::Purple => comp::object::Body::FireworkPurple, + item::Reagent::Red => comp::object::Body::FireworkRed, + item::Reagent::Yellow => comp::object::Body::FireworkYellow, + }, item::Throwable::TrainingDummy => comp::object::Body::TrainingDummy, }) .with(comp::Pos(pos.0 + Vec3::unit_z() * 0.25)) @@ -427,8 +440,18 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv item::Throwable::Bomb => { new_entity = new_entity.with(comp::Object::Bomb { owner: uid }); }, - item::Throwable::Firework => { - new_entity = new_entity.with(comp::Object::Firework { owner: uid }); + item::Throwable::Firework(reagent) => { + new_entity = new_entity + .with(comp::Object::Firework { + owner: uid, + reagent, + }) + .with(LightEmitter { + animated: true, + flicker: 2.0, + strength: 2.0, + col: Rgb::new(1.0, 1.0, 0.0), + }); }, item::Throwable::TrainingDummy => { new_entity = new_entity.with(comp::Stats::new( diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 412d9a536a..948fbc6355 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -55,7 +55,8 @@ impl Server { power, owner, friendly_damage, - } => handle_explosion(&self, pos, power, owner, friendly_damage), + reagent, + } => handle_explosion(&self, pos, power, owner, friendly_damage, reagent), ServerEvent::Shoot { entity, dir, diff --git a/server/src/sys/object.rs b/server/src/sys/object.rs index 81a2200fbe..8a59fd32a6 100644 --- a/server/src/sys/object.rs +++ b/server/src/sys/object.rs @@ -26,8 +26,14 @@ impl<'a> System<'a> for Sys { let mut server_emitter = server_bus.emitter(); // Objects - for (entity, pos, vel, physics, object) in - (&entities, &positions, &velocities, &physics_states, &mut objects).join() + for (entity, pos, vel, physics, object) in ( + &entities, + &positions, + &velocities, + &physics_states, + &mut objects, + ) + .join() { match object { Object::Bomb { owner } => { @@ -41,11 +47,12 @@ impl<'a> System<'a> for Sys { power: 4.0, owner: *owner, friendly_damage: true, + reagent: None, }); } }, - Object::Firework { owner } => { - if physics.on_surface().is_some() || vel.0.z < 0.0 { + Object::Firework { owner, reagent } => { + if vel.0.z < 0.0 { server_emitter.emit(ServerEvent::Destroy { entity, cause: HealthSource::Suicide, @@ -55,6 +62,7 @@ impl<'a> System<'a> for Sys { power: 4.0, owner: *owner, friendly_damage: true, + reagent: Some(*reagent), }); } }, diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index 783056271b..8c47867aa1 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -273,7 +273,7 @@ impl SfxMgr { } match outcome { - Outcome::Explosion { pos, power } => { + Outcome::Explosion { pos, power, .. } => { audio.play_sfx( // TODO: from sfx triggers config "voxygen.audio.sfx.explosion", diff --git a/voxygen/src/lib.rs b/voxygen/src/lib.rs index ccec393b41..9eeeb17318 100644 --- a/voxygen/src/lib.rs +++ b/voxygen/src/lib.rs @@ -1,6 +1,6 @@ #![deny(unsafe_code)] #![allow(clippy::option_map_unit_fn)] -#![feature(drain_filter, bool_to_option)] +#![feature(drain_filter, bool_to_option, or_patterns)] #![recursion_limit = "2048"] #[macro_use] diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs index eae013242d..616e3158c4 100644 --- a/voxygen/src/render/pipelines/particle.rs +++ b/voxygen/src/render/pipelines/particle.rs @@ -87,6 +87,11 @@ pub enum ParticleMode { CampfireFire = 1, GunPowderSpark = 2, Shrapnel = 3, + FireworkBlue = 4, + FireworkGreen = 5, + FireworkPurple = 6, + FireworkRed = 7, + FireworkYellow = 8, } impl ParticleMode { diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs index 6489891367..01c7044073 100644 --- a/voxygen/src/scene/figure/load.rs +++ b/voxygen/src/scene/figure/load.rs @@ -3418,7 +3418,26 @@ pub fn mesh_object( Vec3::new(-0.5, -6.0, -1.5), ), Body::Bomb => ("object.bomb", Vec3::new(-5.5, -5.5, 0.0)), - Body::Firework => ("object.firework", Vec3::new(-5.5, -5.5, 0.0)), + Body::FireworkBlue => ( + "weapon.projectile.fireworks_blue-0", + Vec3::new(0.0, 0.0, 0.0), + ), + Body::FireworkGreen => ( + "weapon.projectile.fireworks_green-0", + Vec3::new(0.0, 0.0, 0.0), + ), + Body::FireworkPurple => ( + "weapon.projectile.fireworks_purple-0", + Vec3::new(0.0, 0.0, 0.0), + ), + Body::FireworkRed => ( + "weapon.projectile.fireworks_red-0", + Vec3::new(0.0, 0.0, 0.0), + ), + Body::FireworkYellow => ( + "weapon.projectile.fireworks_yellow-0", + Vec3::new(0.0, 0.0, 0.0), + ), Body::Scarecrow => ("object.scarecrow", Vec3::new(-9.5, -4.0, 0.0)), Body::Cauldron => ("object.cauldron", Vec3::new(-10.0, -10.0, 0.0)), Body::ChestVines => ("object.chest_vines", Vec3::new(-7.5, -6.0, 0.0)), diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 5eacf0870b..c4e338d463 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -26,6 +26,7 @@ use common::{ terrain::{BlockKind, TerrainChunk}, vol::ReadVol, }; +use comp::item::Reagent; use specs::{Entity as EcsEntity, Join, WorldExt}; use vek::*; @@ -203,9 +204,31 @@ impl Scene { self.sfx_mgr.handle_outcome(&outcome, audio); match outcome { - Outcome::Explosion { pos, power, .. } => self.event_lights.push(EventLight { - light: Light::new(*pos, Rgb::new(1.0, 0.5, 0.0), *power * 2.5), - timeout: 0.5, + Outcome::Explosion { + pos, + power, + reagent, + } => self.event_lights.push(EventLight { + light: Light::new( + *pos, + match reagent { + Some(Reagent::Blue) => Rgb::new(0.0, 0.0, 1.0), + Some(Reagent::Green) => Rgb::new(0.0, 1.0, 0.0), + Some(Reagent::Purple) => Rgb::new(1.0, 0.0, 1.0), + Some(Reagent::Red) => Rgb::new(1.0, 0.0, 0.0), + Some(Reagent::Yellow) => Rgb::new(1.0, 1.0, 0.0), + None => Rgb::new(1.0, 0.5, 0.0), + }, + *power + * match reagent { + Some(_) => 5.0, + None => 2.5, + }, + ), + timeout: match reagent { + Some(_) => 1.0, + None => 0.5, + }, fadeout: |timeout| timeout * 2.0, }), Outcome::ProjectileShot { .. } => {}, diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index f797ba9e89..aff6107727 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -8,7 +8,7 @@ use crate::{ }; use common::{ assets, - comp::{object, Body, CharacterState, Pos}, + comp::{item::Reagent, object, Body, CharacterState, Pos}, figure::Segment, outcome::Outcome, }; @@ -48,15 +48,27 @@ impl ParticleMgr { let mut rng = rand::thread_rng(); match outcome { - Outcome::Explosion { pos, power } => { + Outcome::Explosion { + pos, + power, + reagent, + } => { for _ in 0..150 { self.particles.push(Particle::new( - Duration::from_millis(250), + Duration::from_millis(if reagent.is_some() { 1000 } else { 250 }), time, - ParticleMode::Shrapnel, + match reagent { + Some(Reagent::Blue) => ParticleMode::FireworkBlue, + Some(Reagent::Green) => ParticleMode::FireworkGreen, + Some(Reagent::Purple) => ParticleMode::FireworkPurple, + Some(Reagent::Red) => ParticleMode::FireworkRed, + Some(Reagent::Yellow) => ParticleMode::FireworkYellow, + None => ParticleMode::Shrapnel, + }, *pos, )); } + for _ in 0..200 { self.particles.push(Particle::new( Duration::from_secs(4), @@ -113,7 +125,14 @@ impl ParticleMgr { Body::Object(object::Body::BoltFireBig) => { self.maintain_boltfirebig_particles(scene_data, pos) }, - Body::Object(object::Body::Bomb) => self.maintain_bomb_particles(scene_data, pos), + Body::Object( + object::Body::Bomb + | object::Body::FireworkBlue + | object::Body::FireworkGreen + | object::Body::FireworkPurple + | object::Body::FireworkRed + | object::Body::FireworkYellow, + ) => self.maintain_bomb_particles(scene_data, pos), _ => {}, } }