diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/Recipes.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/Recipes.xml index 0d5287f111..90f4bd8dd7 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/Recipes.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/Recipes.xml @@ -7,17214 +7,30899 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java index 07d2f9cf70..980dbf1447 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -90,12 +90,16 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("CpHealOverTime", CpHealOverTime::new); EffectHandler.getInstance().registerHandler("CpHealPercent", CpHealPercent::new); EffectHandler.getInstance().registerHandler("CpRegen", CpRegen::new); + EffectHandler.getInstance().registerHandler("CraftingCritical", CraftingCritical::new); + EffectHandler.getInstance().registerHandler("CreateCommonItem", CreateCommonItem::new); + EffectHandler.getInstance().registerHandler("CreateItem", CreateItem::new); EffectHandler.getInstance().registerHandler("CreateItemRandom", CreateItemRandom::new); EffectHandler.getInstance().registerHandler("CriticalDamage", CriticalDamage::new); EffectHandler.getInstance().registerHandler("CriticalDamagePosition", CriticalDamagePosition::new); EffectHandler.getInstance().registerHandler("CriticalRate", CriticalRate::new); EffectHandler.getInstance().registerHandler("CriticalRatePositionBonus", CriticalRatePositionBonus::new); EffectHandler.getInstance().registerHandler("CrystalGradeModify", CrystalGradeModify::new); + EffectHandler.getInstance().registerHandler("Crystallize", Crystallize::new); EffectHandler.getInstance().registerHandler("CubicMastery", CubicMastery::new); EffectHandler.getInstance().registerHandler("DamageBlock", DamageBlock::new); EffectHandler.getInstance().registerHandler("DamageShield", DamageShield::new); @@ -265,6 +269,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("ReflectSkill", ReflectSkill::new); EffectHandler.getInstance().registerHandler("RefuelAirship", RefuelAirship::new); EffectHandler.getInstance().registerHandler("Relax", Relax::new); + EffectHandler.getInstance().registerHandler("RemoveEquipPenalty", RemoveEquipPenalty::new); EffectHandler.getInstance().registerHandler("ResetInstanceEntry", ResetInstanceEntry::new); EffectHandler.getInstance().registerHandler("ResistAbnormalByCategory", ResistAbnormalByCategory::new); EffectHandler.getInstance().registerHandler("ResistDDMagic", ResistDDMagic::new); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2ManufactureItem.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CraftingCritical.java similarity index 56% rename from L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2ManufactureItem.java rename to L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CraftingCritical.java index 96d3dd2776..861ca9f57a 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2ManufactureItem.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CraftingCritical.java @@ -1,48 +1,31 @@ -/* - * This file is part of the L2J Mobius project. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.l2jmobius.gameserver.model; - -import com.l2jmobius.gameserver.data.xml.impl.RecipeData; - -public class L2ManufactureItem -{ - private final int _recipeId; - private final long _cost; - private final boolean _isDwarven; - - public L2ManufactureItem(int recipeId, long cost) - { - _recipeId = recipeId; - _cost = cost; - _isDwarven = RecipeData.getInstance().getRecipeList(_recipeId).isDwarvenRecipe(); - } - - public int getRecipeId() - { - return _recipeId; - } - - public long getCost() - { - return _cost; - } - - public boolean isDwarven() - { - return _isDwarven; - } -} +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Nik + */ +public class CraftingCritical extends AbstractStatAddEffect +{ + public CraftingCritical(StatsSet params) + { + super(params, Stats.CRAFTING_CRITICAL); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateCommonItem.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateCommonItem.java new file mode 100644 index 0000000000..d189eb6f48 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateCommonItem.java @@ -0,0 +1,64 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.effects.AbstractEffect; +import com.l2jmobius.gameserver.model.skills.BuffInfo; +import com.l2jmobius.gameserver.model.skills.Skill; + +/** + * An effect that allows the player to create common recipe items up to a certain level. + * @author Nik + */ +public final class CreateCommonItem extends AbstractEffect +{ + private final int _recipeLevel; + + public CreateCommonItem(StatsSet params) + { + _recipeLevel = params.getInt("value"); + } + + @Override + public boolean canStart(BuffInfo info) + { + return info.getEffected().isPlayer(); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + final L2PcInstance player = effected.getActingPlayer(); + if (player != null) + { + player.setCreateCommonItemLevel(_recipeLevel); + } + } + + @Override + public void onExit(BuffInfo info) + { + final L2PcInstance player = info.getEffected().getActingPlayer(); + if (player != null) + { + player.setCreateCommonItemLevel(0); + } + } +} \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateItem.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateItem.java new file mode 100644 index 0000000000..a18650feb0 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CreateItem.java @@ -0,0 +1,64 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.effects.AbstractEffect; +import com.l2jmobius.gameserver.model.skills.BuffInfo; +import com.l2jmobius.gameserver.model.skills.Skill; + +/** + * An effect that allows the player to create dwarven recipe items up to a certain level. + * @author Nik + */ +public final class CreateItem extends AbstractEffect +{ + private final int _recipeLevel; + + public CreateItem(StatsSet params) + { + _recipeLevel = params.getInt("value"); + } + + @Override + public boolean canStart(BuffInfo info) + { + return info.getEffected().isPlayer(); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + final L2PcInstance player = effected.getActingPlayer(); + if (player != null) + { + player.setCreateItemLevel(_recipeLevel); + } + } + + @Override + public void onExit(BuffInfo info) + { + final L2PcInstance player = info.getEffected().getActingPlayer(); + if (player != null) + { + player.setCreateItemLevel(0); + } + } +} \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CrystalGradeModify.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CrystalGradeModify.java index 248727ab7d..49807b42a7 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CrystalGradeModify.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/CrystalGradeModify.java @@ -29,11 +29,11 @@ import com.l2jmobius.gameserver.model.skills.Skill; */ public final class CrystalGradeModify extends AbstractEffect { - private final int _grade; + private final int _amount; public CrystalGradeModify(StatsSet params) { - _grade = params.getInt("grade", 0); + _amount = params.getInt("_amount", 0); } @Override @@ -45,7 +45,7 @@ public final class CrystalGradeModify extends AbstractEffect @Override public void onStart(L2Character effector, L2Character effected, Skill skill) { - effected.getActingPlayer().setExpertisePenaltyBonus(_grade); + effected.getActingPlayer().setExpertisePenaltyBonus(_amount); } @Override diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/Crystallize.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/Crystallize.java new file mode 100644 index 0000000000..070fbd5193 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/Crystallize.java @@ -0,0 +1,65 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.enums.ItemGrade; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.effects.AbstractEffect; +import com.l2jmobius.gameserver.model.skills.BuffInfo; +import com.l2jmobius.gameserver.model.skills.Skill; + +/** + * An effect that allows the player to crystallize items up to a certain grade. + * @author Nik + */ +public final class Crystallize extends AbstractEffect +{ + private final ItemGrade _grade; + + public Crystallize(StatsSet params) + { + _grade = params.getEnum("grade", ItemGrade.class); + } + + @Override + public boolean canStart(BuffInfo info) + { + return info.getEffected().isPlayer(); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + final L2PcInstance player = effected.getActingPlayer(); + if (player != null) + { + player.setCrystallizeGrade(_grade); + } + } + + @Override + public void onExit(BuffInfo info) + { + final L2PcInstance player = info.getEffected().getActingPlayer(); + if (player != null) + { + player.setCrystallizeGrade(null); + } + } +} \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenCommonRecipeBook.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenCommonRecipeBook.java index 78280f5bd8..a353ce45d2 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenCommonRecipeBook.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenCommonRecipeBook.java @@ -16,7 +16,6 @@ */ package handlers.effecthandlers; -import com.l2jmobius.gameserver.RecipeController; import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; @@ -25,6 +24,7 @@ import com.l2jmobius.gameserver.model.effects.AbstractEffect; import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.model.skills.Skill; import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList; /** * Open Common Recipe Book effect implementation. @@ -45,18 +45,24 @@ public final class OpenCommonRecipeBook extends AbstractEffect @Override public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) { - if (!effector.isPlayer()) + final L2PcInstance casterPlayer = effector.getActingPlayer(); + if (casterPlayer == null) { return; } - final L2PcInstance player = effector.getActingPlayer(); - if (player.getPrivateStoreType() != PrivateStoreType.NONE) + if (casterPlayer.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) { - player.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE); + casterPlayer.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING); return; } - RecipeController.getInstance().requestBookOpen(player, false); + if (casterPlayer.isProcessingTransaction()) + { + casterPlayer.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE); + return; + } + + casterPlayer.sendPacket(new RecipeBookItemList(casterPlayer, false)); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenDwarfRecipeBook.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenDwarfRecipeBook.java index d781e6d6cb..68493ad7cc 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenDwarfRecipeBook.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/OpenDwarfRecipeBook.java @@ -16,7 +16,6 @@ */ package handlers.effecthandlers; -import com.l2jmobius.gameserver.RecipeController; import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; @@ -25,6 +24,7 @@ import com.l2jmobius.gameserver.model.effects.AbstractEffect; import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.model.skills.Skill; import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList; /** * Open Dwarf Recipe Book effect implementation. @@ -45,18 +45,24 @@ public final class OpenDwarfRecipeBook extends AbstractEffect @Override public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) { - if (!effector.isPlayer()) + final L2PcInstance casterPlayer = effector.getActingPlayer(); + if (casterPlayer == null) { return; } - final L2PcInstance player = effector.getActingPlayer(); - if (player.getPrivateStoreType() != PrivateStoreType.NONE) + if (casterPlayer.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) { - player.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE); + casterPlayer.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING); return; } - RecipeController.getInstance().requestBookOpen(player, true); + if (casterPlayer.isProcessingTransaction()) + { + casterPlayer.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE); + return; + } + + casterPlayer.sendPacket(new RecipeBookItemList(casterPlayer, true)); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/RemoveEquipPenalty.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/RemoveEquipPenalty.java new file mode 100644 index 0000000000..4841f0a023 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/RemoveEquipPenalty.java @@ -0,0 +1,65 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.effects.AbstractEffect; +import com.l2jmobius.gameserver.model.items.type.CrystalType; +import com.l2jmobius.gameserver.model.skills.BuffInfo; +import com.l2jmobius.gameserver.model.skills.Skill; + +/** + * An effect that removes equipment grade penalty. Its the base effect for the grade penalty mechanics. + * @author Nik + */ +public final class RemoveEquipPenalty extends AbstractEffect +{ + private final CrystalType _grade; + + public RemoveEquipPenalty(StatsSet params) + { + _grade = params.getEnum("grade", CrystalType.class); + } + + @Override + public boolean canStart(BuffInfo info) + { + return info.getEffected().isPlayer(); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + final L2PcInstance player = effected.getActingPlayer(); + if (player != null) + { + player.setExpertiseLevel(_grade); + } + } + + @Override + public void onExit(BuffInfo info) + { + final L2PcInstance player = info.getEffected().getActingPlayer(); + if (player != null) + { + player.setExpertiseLevel(null); + } + } +} \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/CharmOfCourage.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/CharmOfCourage.java index 4b7b0b246d..eef7f6bb11 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/CharmOfCourage.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/CharmOfCourage.java @@ -42,7 +42,7 @@ public class CharmOfCourage implements IItemHandler final L2PcInstance activeChar = playable.getActingPlayer(); int level = activeChar.getLevel(); - final int itemLevel = item.getItem().getCrystalType().getId(); + final int itemLevel = item.getItem().getCrystalType().getLevel(); if (level < 20) { diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/Recipes.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/Recipes.java index 59ca8fcc83..19bc984f6f 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/Recipes.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/itemhandlers/Recipes.java @@ -18,9 +18,9 @@ package handlers.itemhandlers; import com.l2jmobius.gameserver.data.xml.impl.RecipeData; import com.l2jmobius.gameserver.handler.IItemHandler; -import com.l2jmobius.gameserver.model.L2RecipeList; import com.l2jmobius.gameserver.model.actor.L2Playable; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; @@ -40,15 +40,16 @@ public class Recipes implements IItemHandler } final L2PcInstance activeChar = playable.getActingPlayer(); - if (activeChar.isInCraftMode()) + if (activeChar.isCrafting()) { activeChar.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING); return false; } - final L2RecipeList rp = RecipeData.getInstance().getRecipeByItemId(item.getId()); + final RecipeHolder rp = RecipeData.getInstance().getRecipeByRecipeItemId(item.getId()); if (rp == null) { + activeChar.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT); return false; } @@ -63,15 +64,15 @@ public class Recipes implements IItemHandler boolean recipeLimit = false; if (rp.isDwarvenRecipe()) { - canCraft = activeChar.hasDwarvenCraft(); - recipeLevel = (rp.getLevel() > activeChar.getDwarvenCraft()); - recipeLimit = (activeChar.getDwarvenRecipeBook().length >= activeChar.getDwarfRecipeLimit()); + canCraft = activeChar.getCreateItemLevel() > 0; + recipeLevel = (rp.getLevel() > activeChar.getCreateItemLevel()); + recipeLimit = (activeChar.getDwarvenRecipeBook().size() >= activeChar.getDwarfRecipeLimit()); } else { - canCraft = activeChar.hasCommonCraft(); - recipeLevel = (rp.getLevel() > activeChar.getCommonCraft()); - recipeLimit = (activeChar.getCommonRecipeBook().length >= activeChar.getCommonRecipeLimit()); + canCraft = activeChar.getCreateCommonItemLevel() > 0; + recipeLevel = (rp.getLevel() > activeChar.getCreateCommonItemLevel()); + recipeLimit = (activeChar.getCommonRecipeBook().size() >= activeChar.getCommonRecipeLimit()); } if (!canCraft) diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/playeractions/SocialAction.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/playeractions/SocialAction.java index 1e34a0d148..766844c759 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/playeractions/SocialAction.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/playeractions/SocialAction.java @@ -119,7 +119,7 @@ public final class SocialAction implements IPlayerActionHandler } SystemMessage sm; - if (player.isInStoreMode() || player.isInCraftMode()) + if (player.isInStoreMode() || player.isCrafting()) { sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_PRIVATE_STORE_MODE_OR_IN_A_BATTLE_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION); sm.addPcName(player); @@ -198,7 +198,7 @@ public final class SocialAction implements IPlayerActionHandler // Checks for partner. final L2PcInstance partner = target.getActingPlayer(); - if (partner.isInStoreMode() || partner.isInCraftMode()) + if (partner.isInStoreMode() || partner.isCrafting()) { sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_PRIVATE_STORE_MODE_OR_IN_A_BATTLE_AND_CANNOT_BE_REQUESTED_FOR_A_COUPLE_ACTION); sm.addPcName(partner); diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00100-00199.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00100-00199.xml index 4c6466021c..f84f600ad1 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00100-00199.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00100-00199.xml @@ -2727,6 +2727,27 @@ P 5 + + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + + + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml index 78e7b47318..ef9977ac2f 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml @@ -2434,6 +2434,22 @@ P 5 + + + + D + C + B + A + S + S80 + S80 + R + R95 + R99 + + + @@ -2615,6 +2631,18 @@ P 5 + + + + D + C + B + A + S + R + + + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/01300-01399.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/01300-01399.xml index 60f0c36643..490d054c7e 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/01300-01399.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/01300-01399.xml @@ -666,6 +666,22 @@ P 5 + + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/10300-10399.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/10300-10399.xml index b752c643f4..1b64d26c36 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/10300-10399.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/10300-10399.xml @@ -509,10 +509,25 @@ - icon.skill10312 + + 85 + 90 + 95 + 99 + P + + + + 2.4 + 3.8 + 4.2 + 5.4 + + + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/22000-22099.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/22000-22099.xml index 9b757cf870..d0c88e95f3 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/22000-22099.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/22000-22099.xml @@ -1268,10 +1268,10 @@ - + 3 5 - + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/26000-26099.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/26000-26099.xml index c4badadcad..3ab9f257c0 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/26000-26099.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/26000-26099.xml @@ -1320,13 +1320,13 @@ - + 1 2 3 4 5 - + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt index c4f6ad75ed..a9b94b0bf3 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt @@ -59,12 +59,16 @@ CpHealOverTime: Increases current CP by a given amount over time. CpHealPercent: Increases current CP by a given percentage amount. Cp: Increases current CP by a static amount. CpRegen: CP Regeneration stat. +CraftingCritical: Crafting critical stat. +CreateCommonItem: Allows the player to create common recipe items up to a certain level. +CreateItem: Allows the player to create dwarven recipe items up to a certain level. CreateItemRandom: Creates an item randomly from a given list. All extractable items with chances to get different items are using this effect. CriticalDamage: Critical Damage stat. CriticalDamagePosition: Critical Damage depending on position stat. CriticalRate: Critical Rate stat. CriticalRatePositionBonus: Critical Rate depending on position stat. Ignores the critical rate cap of 500. CrystalGradeModify: Sets your Expertise Grade level. With this effect you can make lv. 40 player (C Grade) to wear S grade. +Crystallize: Allows the player to crystallize items up to a certain grade. CubicMastery: Max cubics stat. DamageBlock: Blocks Hp or Mp damage/heal. DamageShield: Reflect damage percentage stat. @@ -233,6 +237,7 @@ ReflectMagic: Deflects magical damage back to the attacker. ReflectSkill: Deflects physical/magical debuffs back to the attacker. RefuelAirship: Increases Airship's fuel. Relax: Sits down and increases HP regeneration until full. +RemoveEquipPenalty: Removes equipment grade penalty. Its the base effect for the grade penalty mechanics. ResetInstanceEntry: Resets instance re-entry time. (l2jmobius) ResistAbnormalByCategory: Buff/debuff resist stat. ResistDDMagic: Magic resist stat (magic attack 50% effective or 1 damage) diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/Recipes.xsd b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/Recipes.xsd index 52c9af31ff..ffa4478bef 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/Recipes.xsd +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/Recipes.xsd @@ -2,88 +2,68 @@ - - + + - - + + - - - - - - - - - - + + + + + + + + - + - - + + + + + + + + + - + - - + + + + + + + + - + - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/skills.xsd b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/skills.xsd index 2b9bb3042d..24f4246eb5 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/skills.xsd +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/xsd/skills.xsd @@ -1197,6 +1197,21 @@ + + + + + + + + + + + + + + + @@ -2037,21 +2052,6 @@ - - - - - - - - - - - - - - - diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/RecipeController.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/RecipeController.java deleted file mode 100644 index 0bd69dc604..0000000000 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/RecipeController.java +++ /dev/null @@ -1,785 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.l2jmobius.gameserver; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; - -import com.l2jmobius.Config; -import com.l2jmobius.commons.util.Rnd; -import com.l2jmobius.gameserver.data.xml.impl.RecipeData; -import com.l2jmobius.gameserver.datatables.ItemTable; -import com.l2jmobius.gameserver.enums.StatType; -import com.l2jmobius.gameserver.enums.StatusUpdateType; -import com.l2jmobius.gameserver.model.L2ManufactureItem; -import com.l2jmobius.gameserver.model.L2RecipeInstance; -import com.l2jmobius.gameserver.model.L2RecipeList; -import com.l2jmobius.gameserver.model.L2RecipeStatInstance; -import com.l2jmobius.gameserver.model.TempItem; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; -import com.l2jmobius.gameserver.model.itemcontainer.Inventory; -import com.l2jmobius.gameserver.model.items.L2Item; -import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; -import com.l2jmobius.gameserver.model.skills.CommonSkill; -import com.l2jmobius.gameserver.model.skills.Skill; -import com.l2jmobius.gameserver.model.stats.Stats; -import com.l2jmobius.gameserver.network.SystemMessageId; -import com.l2jmobius.gameserver.network.serverpackets.ActionFailed; -import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight; -import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; -import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList; -import com.l2jmobius.gameserver.network.serverpackets.RecipeItemMakeInfo; -import com.l2jmobius.gameserver.network.serverpackets.RecipeShopItemInfo; -import com.l2jmobius.gameserver.network.serverpackets.SetupGauge; -import com.l2jmobius.gameserver.network.serverpackets.StatusUpdate; -import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; -import com.l2jmobius.gameserver.util.Util; - -public class RecipeController -{ - protected static final Map _activeMakers = new ConcurrentHashMap<>(); - - protected RecipeController() - { - } - - public void requestBookOpen(L2PcInstance player, boolean isDwarvenCraft) - { - // Check if player is trying to alter recipe book while engaged in manufacturing. - if (!_activeMakers.containsKey(player.getObjectId())) - { - final RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft, player.getMaxMp()); - response.addRecipes(isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook()); - player.sendPacket(response); - return; - } - player.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING); - } - - public void requestMakeItemAbort(L2PcInstance player) - { - _activeMakers.remove(player.getObjectId()); // TODO: anything else here? - } - - public void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance player) - { - final L2RecipeList recipeList = RecipeData.getInstance().getValidRecipeList(player, recipeListId); - if (recipeList == null) - { - return; - } - - final List dwarfRecipes = Arrays.asList(manufacturer.getDwarvenRecipeBook()); - final List commonRecipes = Arrays.asList(manufacturer.getCommonRecipeBook()); - - if (!dwarfRecipes.contains(recipeList) && !commonRecipes.contains(recipeList)) - { - Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH); - return; - } - - // Check if manufacturer is under manufacturing store or private store. - if (Config.ALT_GAME_CREATION && _activeMakers.containsKey(manufacturer.getObjectId())) - { - player.sendPacket(SystemMessageId.PLEASE_CLOSE_THE_SETUP_WINDOW_FOR_YOUR_PRIVATE_WORKSHOP_OR_PRIVATE_STORE_AND_TRY_AGAIN); - return; - } - - final RecipeItemMaker maker = new RecipeItemMaker(manufacturer, recipeList, player); - if (maker._isValid) - { - if (Config.ALT_GAME_CREATION) - { - _activeMakers.put(manufacturer.getObjectId(), maker); - ThreadPoolManager.schedule(maker, 100); - } - else - { - maker.run(); - } - } - } - - public void requestMakeItem(L2PcInstance player, int recipeListId) - { - // Check if player is trying to operate a private store or private workshop while engaged in combat. - if (player.isInCombat() || player.isInDuel()) - { - player.sendPacket(SystemMessageId.WHILE_YOU_ARE_ENGAGED_IN_COMBAT_YOU_CANNOT_OPERATE_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP); - return; - } - - final L2RecipeList recipeList = RecipeData.getInstance().getValidRecipeList(player, recipeListId); - if (recipeList == null) - { - return; - } - - final List dwarfRecipes = Arrays.asList(player.getDwarvenRecipeBook()); - final List commonRecipes = Arrays.asList(player.getCommonRecipeBook()); - - if (!dwarfRecipes.contains(recipeList) && !commonRecipes.contains(recipeList)) - { - Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH); - return; - } - - // Check if player is busy (possible if alt game creation is enabled) - if (Config.ALT_GAME_CREATION && _activeMakers.containsKey(player.getObjectId())) - { - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_S1); - sm.addItemName(recipeList.getItemId()); - sm.addString("You are busy creating."); - player.sendPacket(sm); - return; - } - - final RecipeItemMaker maker = new RecipeItemMaker(player, recipeList, player); - if (maker._isValid) - { - if (Config.ALT_GAME_CREATION) - { - _activeMakers.put(player.getObjectId(), maker); - ThreadPoolManager.schedule(maker, 100); - } - else - { - maker.run(); - } - } - } - - private static class RecipeItemMaker implements Runnable - { - private static final Logger LOGGER = Logger.getLogger(RecipeItemMaker.class.getName()); - protected boolean _isValid; - protected List _items = null; - protected final L2RecipeList _recipeList; - protected final L2PcInstance _player; // "crafter" - protected final L2PcInstance _target; // "customer" - protected final Skill _skill; - protected final int _skillId; - protected final int _skillLevel; - protected int _creationPasses = 1; - protected int _itemGrab; - protected int _exp = -1; - protected int _sp = -1; - protected long _price; - protected int _totalItems; - protected int _delay; - - public RecipeItemMaker(L2PcInstance pPlayer, L2RecipeList pRecipeList, L2PcInstance pTarget) - { - _player = pPlayer; - _target = pTarget; - _recipeList = pRecipeList; - - _isValid = false; - _skillId = _recipeList.isDwarvenRecipe() ? CommonSkill.CREATE_DWARVEN.getId() : CommonSkill.CREATE_COMMON.getId(); - _skillLevel = _player.getSkillLevel(_skillId); - _skill = _player.getKnownSkill(_skillId); - - _player.isInCraftMode(true); - - if (_player.isAlikeDead()) - { - _player.sendPacket(ActionFailed.STATIC_PACKET); - abort(); - return; - } - - if (_target.isAlikeDead()) - { - _target.sendPacket(ActionFailed.STATIC_PACKET); - abort(); - return; - } - - if (_target.isProcessingTransaction()) - { - _target.sendPacket(ActionFailed.STATIC_PACKET); - abort(); - return; - } - - if (_player.isProcessingTransaction()) - { - _player.sendPacket(ActionFailed.STATIC_PACKET); - abort(); - return; - } - - // validate recipe list - if (_recipeList.getRecipes().length == 0) - { - _player.sendPacket(ActionFailed.STATIC_PACKET); - abort(); - return; - } - - // validate skill level - if (_recipeList.getLevel() > _skillLevel) - { - _player.sendPacket(ActionFailed.STATIC_PACKET); - abort(); - return; - } - - // check that customer can afford to pay for creation services - if (_player != _target) - { - final L2ManufactureItem item = _player.getManufactureItems().get(_recipeList.getId()); - if (item != null) - { - _price = item.getCost(); - if (_target.getAdena() < _price) // check price - { - _target.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA); - abort(); - return; - } - } - } - - // make temporary items - _items = listItems(false); - if (_items == null) - { - abort(); - return; - } - - for (TempItem i : _items) - { - _totalItems += i.getQuantity(); - } - - // initial statUse checks - if (!calculateStatUse(false, false)) - { - abort(); - return; - } - - // initial AltStatChange checks - if (Config.ALT_GAME_CREATION) - { - calculateAltStatChange(); - } - - updateMakeInfo(true); - updateCurMp(); - updateCurLoad(); - - _player.isInCraftMode(false); - _isValid = true; - } - - @Override - public void run() - { - if (!Config.IS_CRAFTING_ENABLED) - { - _target.sendMessage("Item creation is currently disabled."); - abort(); - return; - } - - if ((_player == null) || (_target == null)) - { - LOGGER.warning("player or target == null (disconnected?), aborting" + _target + _player); - abort(); - return; - } - - if (!_player.isOnline() || !_target.isOnline()) - { - LOGGER.warning("player or target is not online, aborting " + _target + _player); - abort(); - return; - } - - if (Config.ALT_GAME_CREATION && !_activeMakers.containsKey(_player.getObjectId())) - { - if (_target != _player) - { - _target.sendMessage("Manufacture aborted"); - _player.sendMessage("Manufacture aborted"); - } - else - { - _player.sendMessage("Item creation aborted"); - } - - abort(); - return; - } - - if (Config.ALT_GAME_CREATION && !_items.isEmpty()) - { - - if (!calculateStatUse(true, true)) - { - return; // check stat use - } - updateCurMp(); // update craft window mp bar - - grabSomeItems(); // grab (equip) some more items with a nice msg to player - - // if still not empty, schedule another pass - if (!_items.isEmpty()) - { - _delay = (int) (Config.ALT_GAME_CREATION_SPEED * _player.getStat().getReuseTime(_skill) * GameTimeController.TICKS_PER_SECOND * GameTimeController.MILLIS_IN_TICK); - - // FIXME: please fix this packet to show crafting animation (somebody) - final MagicSkillUse msk = new MagicSkillUse(_player, _skillId, _skillLevel, _delay, 0); - _player.broadcastPacket(msk); - - _player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay)); - ThreadPoolManager.schedule(this, 100 + _delay); - } - else - { - // for alt mode, sleep delay msec before finishing - _player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay)); - - try - { - Thread.sleep(_delay); - } - catch (InterruptedException e) - { - } - finally - { - finishCrafting(); - } - } - } // for old craft mode just finish - else - { - finishCrafting(); - } - } - - private void finishCrafting() - { - if (!Config.ALT_GAME_CREATION) - { - calculateStatUse(false, true); - } - - // first take adena for manufacture - if ((_target != _player) && (_price > 0)) // customer must pay for services - { - // attempt to pay for item - final L2ItemInstance adenatransfer = _target.transferItem("PayManufacture", _target.getInventory().getAdenaInstance().getObjectId(), _price, _player.getInventory(), _player); - - if (adenatransfer == null) - { - _target.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA); - abort(); - return; - } - } - - _items = listItems(true); // this line actually takes materials from inventory - if (_items == null) - { - // handle possible cheaters here - // (they click craft then try to get rid of items in order to get free craft) - } - else if ((Rnd.get(100) < _recipeList.getSuccessRate()) || _target.tryLuck()) - { - rewardPlayer(_target); // and immediately puts created item in its place - updateMakeInfo(true); - } - else - { - if (_target != _player) - { - SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_FAILED_TO_CREATE_S2_FOR_C1_AT_THE_PRICE_OF_S3_ADENA); - msg.addString(_target.getName()); - msg.addItemName(_recipeList.getItemId()); - msg.addLong(_price); - _player.sendPacket(msg); - - msg = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_FAILED_TO_CREATE_S2_AT_THE_PRICE_OF_S3_ADENA); - msg.addString(_player.getName()); - msg.addItemName(_recipeList.getItemId()); - msg.addLong(_price); - _target.sendPacket(msg); - } - else - { - _target.sendPacket(SystemMessageId.YOU_FAILED_AT_MIXING_THE_ITEM); - } - updateMakeInfo(false); - } - // update load and mana bar of craft window - updateCurMp(); - _activeMakers.remove(_player.getObjectId()); - _player.isInCraftMode(false); - _target.sendItemList(false); - } - - private void updateMakeInfo(boolean success) - { - if (_target == _player) - { - _target.sendPacket(new RecipeItemMakeInfo(_recipeList.getId(), _target, success)); - } - else - { - _target.sendPacket(new RecipeShopItemInfo(_player, _recipeList.getId())); - } - } - - private void updateCurLoad() - { - _target.sendPacket(new ExUserInfoInvenWeight(_target)); - } - - private void updateCurMp() - { - final StatusUpdate su = new StatusUpdate(_target); - su.addUpdate(StatusUpdateType.CUR_MP, (int) _target.getCurrentMp()); - _target.sendPacket(su); - } - - private void grabSomeItems() - { - int grabItems = _itemGrab; - while ((grabItems > 0) && !_items.isEmpty()) - { - final TempItem item = _items.get(0); - - int count = item.getQuantity(); - if (count >= grabItems) - { - count = grabItems; - } - - item.setQuantity(item.getQuantity() - count); - if (item.getQuantity() <= 0) - { - _items.remove(0); - } - else - { - _items.set(0, item); - } - - grabItems -= count; - - if (_target == _player) - { - final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.EQUIPPED_S1_S2); // you equipped ... - sm.addLong(count); - sm.addItemName(item.getItemId()); - _player.sendPacket(sm); - } - else - { - _target.sendMessage("Manufacturer " + _player.getName() + " used " + count + " " + item.getItemName()); - } - } - } - - // AltStatChange parameters make their effect here - private void calculateAltStatChange() - { - _itemGrab = _skillLevel; - - for (L2RecipeStatInstance altStatChange : _recipeList.getAltStatChange()) - { - if (altStatChange.getType() == StatType.XP) - { - _exp = altStatChange.getValue(); - } - else if (altStatChange.getType() == StatType.SP) - { - _sp = altStatChange.getValue(); - } - else if (altStatChange.getType() == StatType.GIM) - { - _itemGrab *= altStatChange.getValue(); - } - } - // determine number of creation passes needed - _creationPasses = (_totalItems / _itemGrab) + ((_totalItems % _itemGrab) != 0 ? 1 : 0); - if (_creationPasses < 1) - { - _creationPasses = 1; - } - } - - // StatUse - private boolean calculateStatUse(boolean isWait, boolean isReduce) - { - boolean ret = true; - for (L2RecipeStatInstance statUse : _recipeList.getStatUse()) - { - final double modifiedValue = statUse.getValue() / _creationPasses; - if (statUse.getType() == StatType.HP) - { - // we do not want to kill the player, so its CurrentHP must be greater than the reduce value - if (_player.getCurrentHp() <= modifiedValue) - { - // rest (wait for HP) - if (Config.ALT_GAME_CREATION && isWait) - { - _player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay)); - ThreadPoolManager.schedule(this, 100 + _delay); - } - else - { - _target.sendPacket(SystemMessageId.NOT_ENOUGH_HP); - abort(); - } - ret = false; - } - else if (isReduce) - { - _player.reduceCurrentHp(modifiedValue, _player, _skill); - } - } - else if (statUse.getType() == StatType.MP) - { - if (_player.getCurrentMp() < modifiedValue) - { - // rest (wait for MP) - if (Config.ALT_GAME_CREATION && isWait) - { - _player.sendPacket(new SetupGauge(_player.getObjectId(), 0, _delay)); - ThreadPoolManager.schedule(this, 100 + _delay); - } - else - { - _target.sendPacket(SystemMessageId.NOT_ENOUGH_MP); - abort(); - } - ret = false; - } - else if (isReduce) - { - _player.reduceCurrentMp(modifiedValue); - } - } - else - { - // there is an unknown StatUse value - _target.sendMessage("Recipe error!!!, please tell this to your GM."); - ret = false; - abort(); - } - } - return ret; - } - - private List listItems(boolean remove) - { - final L2RecipeInstance[] recipes = _recipeList.getRecipes(); - final Inventory inv = _target.getInventory(); - final List materials = new ArrayList<>(); - SystemMessage sm; - - for (L2RecipeInstance recipe : recipes) - { - if (recipe.getQuantity() > 0) - { - final L2ItemInstance item = inv.getItemByItemId(recipe.getItemId()); - final long itemQuantityAmount = item == null ? 0 : item.getCount(); - - // check materials - if (itemQuantityAmount < recipe.getQuantity()) - { - sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_MORE_S1_S); - sm.addItemName(recipe.getItemId()); - sm.addLong(recipe.getQuantity() - itemQuantityAmount); - _target.sendPacket(sm); - - abort(); - return null; - } - - // make new temporary object, just for counting purposes - materials.add(new TempItem(item, recipe.getQuantity())); - } - } - - if (remove) - { - for (TempItem tmp : materials) - { - inv.destroyItemByItemId("Manufacture", tmp.getItemId(), tmp.getQuantity(), _target, _player); - - if (tmp.getQuantity() > 1) - { - sm = SystemMessage.getSystemMessage(SystemMessageId.S2_S1_S_DISAPPEARED); - sm.addItemName(tmp.getItemId()); - sm.addLong(tmp.getQuantity()); - _target.sendPacket(sm); - } - else - { - sm = SystemMessage.getSystemMessage(SystemMessageId.S1_DISAPPEARED); - sm.addItemName(tmp.getItemId()); - _target.sendPacket(sm); - } - } - } - return materials; - } - - private void abort() - { - updateMakeInfo(false); - _player.isInCraftMode(false); - _activeMakers.remove(_player.getObjectId()); - } - - private void rewardPlayer(L2PcInstance player) - { - final int rareProdId = _recipeList.getRareItemId(); - int itemId = _recipeList.getItemId(); - int itemCount = _recipeList.getCount(); - final L2Item template = ItemTable.getInstance().getTemplate(itemId); - - // check that the current recipe has a rare production or not - if ((rareProdId != -1) && ((rareProdId == itemId) || Config.CRAFT_MASTERWORK)) - { - if (Rnd.get(100) < _recipeList.getRarity()) - { - itemId = rareProdId; - itemCount = _recipeList.getRareCount(); - } - } - - if (player.tryLuck()) - { - itemCount *= 2; - } - - _target.getInventory().addItem("Manufacture", itemId, itemCount, _target, _player); - - // inform customer of earned item - SystemMessage sm = null; - if (_target != _player) - { - // inform manufacturer of earned profit - if (itemCount == 1) - { - sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HAS_BEEN_CREATED_FOR_C1_AFTER_THE_PAYMENT_OF_S3_ADENA_WAS_RECEIVED); - sm.addString(_target.getName()); - sm.addItemName(itemId); - sm.addLong(_price); - _player.sendPacket(sm); - - sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S2_AFTER_RECEIVING_S3_ADENA); - sm.addString(_player.getName()); - sm.addItemName(itemId); - sm.addLong(_price); - _target.sendPacket(sm); - } - else - { - sm = SystemMessage.getSystemMessage(SystemMessageId.S3_S2_S_HAVE_BEEN_CREATED_FOR_C1_AT_THE_PRICE_OF_S4_ADENA); - sm.addString(_target.getName()); - sm.addInt(itemCount); - sm.addItemName(itemId); - sm.addLong(_price); - _player.sendPacket(sm); - - sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S3_S2_S_AT_THE_PRICE_OF_S4_ADENA); - sm.addString(_player.getName()); - sm.addInt(itemCount); - sm.addItemName(itemId); - sm.addLong(_price); - _target.sendPacket(sm); - } - } - - if (itemCount > 1) - { - sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S2_S1_S); - sm.addItemName(itemId); - sm.addLong(itemCount); - _target.sendPacket(sm); - } - else - { - sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1); - sm.addItemName(itemId); - _target.sendPacket(sm); - } - - if (Config.ALT_GAME_CREATION) - { - final int recipeLevel = _recipeList.getLevel(); - if (_exp < 0) - { - _exp = template.getReferencePrice() * itemCount; - _exp /= recipeLevel; - } - if (_sp < 0) - { - _sp = _exp / 10; - } - if (itemId == rareProdId) - { - _exp *= Config.ALT_GAME_CREATION_RARE_XPSP_RATE; - _sp *= Config.ALT_GAME_CREATION_RARE_XPSP_RATE; - } - - if (_exp < 0) - { - _exp = 0; - } - if (_sp < 0) - { - _sp = 0; - } - - for (int i = _skillLevel; i > recipeLevel; i--) - { - _exp /= 4; - _sp /= 4; - } - - // Added multiplication of Creation speed with XP/SP gain slower crafting -> more XP, - // faster crafting -> less XP you can use ALT_GAME_CREATION_XP_RATE/SP to modify XP/SP gained (default = 1) - _player.addExpAndSp((int) _player.getStat().getValue(Stats.EXPSP_RATE, _exp * Config.ALT_GAME_CREATION_XP_RATE * Config.ALT_GAME_CREATION_SPEED), (int) _player.getStat().getValue(Stats.EXPSP_RATE, _sp * Config.ALT_GAME_CREATION_SP_RATE * Config.ALT_GAME_CREATION_SPEED)); - } - updateMakeInfo(true); // success - } - } - - public static RecipeController getInstance() - { - return SingletonHolder._instance; - } - - private static class SingletonHolder - { - protected static final RecipeController _instance = new RecipeController(); - } -} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java index f88260f46a..d34129376f 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/sql/impl/OfflineTradersTable.java @@ -21,6 +21,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; @@ -28,7 +31,6 @@ import com.l2jmobius.Config; import com.l2jmobius.commons.database.DatabaseFactory; import com.l2jmobius.gameserver.LoginServerThread; import com.l2jmobius.gameserver.enums.PrivateStoreType; -import com.l2jmobius.gameserver.model.L2ManufactureItem; import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.TradeItem; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; @@ -133,12 +135,12 @@ public class OfflineTradersTable continue; } title = pc.getStoreName(); - for (L2ManufactureItem i : pc.getManufactureItems().values()) + for (Entry entry : pc.getManufactureItems().entrySet()) { stm_items.setInt(1, pc.getObjectId()); - stm_items.setInt(2, i.getRecipeId()); + stm_items.setInt(2, entry.getKey()); stm_items.setLong(3, 0); - stm_items.setLong(4, i.getCost()); + stm_items.setLong(4, entry.getValue()); stm_items.executeUpdate(); stm_items.clearParameters(); } @@ -274,10 +276,12 @@ public class OfflineTradersTable } case MANUFACTURE: { + final Map manufactureItems = new HashMap<>(); while (items.next()) { - player.getManufactureItems().put(items.getInt(2), new L2ManufactureItem(items.getInt(2), items.getLong(4))); + manufactureItems.put(items.getInt(2), items.getLong(4)); } + player.setManufactureItems(manufactureItems); player.setStoreName(rs.getString("title")); break; } @@ -407,12 +411,12 @@ public class OfflineTradersTable { title = trader.getStoreName(); } - for (L2ManufactureItem i : trader.getManufactureItems().values()) + for (Entry entry : trader.getManufactureItems().entrySet()) { stm3.setInt(1, trader.getObjectId()); - stm3.setInt(2, i.getRecipeId()); + stm3.setInt(2, entry.getKey()); stm3.setLong(3, 0); - stm3.setLong(4, i.getCost()); + stm3.setLong(4, entry.getValue()); stm3.executeUpdate(); stm3.clearParameters(); } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/RecipeData.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/RecipeData.java index b0b755ac92..80d9297e84 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/RecipeData.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/data/xml/impl/RecipeData.java @@ -18,35 +18,33 @@ package com.l2jmobius.gameserver.data.xml.impl; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; +import java.util.stream.Collectors; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import com.l2jmobius.commons.util.IGameXmlReader; -import com.l2jmobius.gameserver.model.L2RecipeInstance; -import com.l2jmobius.gameserver.model.L2RecipeList; -import com.l2jmobius.gameserver.model.L2RecipeStatInstance; +import com.l2jmobius.gameserver.enums.StatusUpdateType; import com.l2jmobius.gameserver.model.StatsSet; -import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemChanceHolder; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; /** - * The Class RecipeData. - * @author Zoey76 + * @author Nik */ public class RecipeData implements IGameXmlReader { private static final Logger LOGGER = Logger.getLogger(RecipeData.class.getName()); - private final Map _recipes = new HashMap<>(); + private final Map _recipes = new HashMap<>(); - /** - * Instantiates a new recipe data. - */ protected RecipeData() { load(); @@ -63,205 +61,108 @@ public class RecipeData implements IGameXmlReader @Override public void parseDocument(Document doc, File f) { - // TODO: Cleanup checks enforced by XSD. - final List recipePartList = new ArrayList<>(); - final List recipeStatUseList = new ArrayList<>(); - final List recipeAltStatChangeList = new ArrayList<>(); + StatsSet set; + Node att; + NamedNodeMap attrs; for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) { if ("list".equalsIgnoreCase(n.getNodeName())) { - RECIPES_FILE: for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) + for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) { - if ("item".equalsIgnoreCase(d.getNodeName())) + if ("recipe".equalsIgnoreCase(d.getNodeName())) { - recipePartList.clear(); - recipeStatUseList.clear(); - recipeAltStatChangeList.clear(); - final NamedNodeMap attrs = d.getAttributes(); - Node att; - int id = -1; - boolean haveRare = false; - final StatsSet set = new StatsSet(); - - att = attrs.getNamedItem("id"); - if (att == null) + attrs = d.getAttributes(); + set = new StatsSet(); + for (int i = 0; i < attrs.getLength(); i++) { - LOGGER.severe(getClass().getSimpleName() + ": Missing id for recipe item, skipping"); - continue; + att = attrs.item(i); + set.set(att.getNodeName(), att.getNodeValue()); } - id = Integer.parseInt(att.getNodeValue()); - set.set("id", id); - att = attrs.getNamedItem("recipeId"); - if (att == null) - { - LOGGER.severe(getClass().getSimpleName() + ": Missing recipeId for recipe item id: " + id + ", skipping"); - continue; - } - set.set("recipeId", Integer.parseInt(att.getNodeValue())); - - att = attrs.getNamedItem("name"); - if (att == null) - { - LOGGER.severe(getClass().getSimpleName() + ": Missing name for recipe item id: " + id + ", skipping"); - continue; - } - set.set("recipeName", att.getNodeValue()); - - att = attrs.getNamedItem("craftLevel"); - if (att == null) - { - LOGGER.severe(getClass().getSimpleName() + ": Missing level for recipe item id: " + id + ", skipping"); - continue; - } - set.set("craftLevel", Integer.parseInt(att.getNodeValue())); - - att = attrs.getNamedItem("type"); - if (att == null) - { - LOGGER.severe(getClass().getSimpleName() + ": Missing type for recipe item id: " + id + ", skipping"); - continue; - } - set.set("isDwarvenRecipe", att.getNodeValue().equalsIgnoreCase("dwarven")); - - att = attrs.getNamedItem("successRate"); - if (att == null) - { - LOGGER.severe(getClass().getSimpleName() + ": Missing successRate for recipe item id: " + id + ", skipping"); - continue; - } - set.set("successRate", Integer.parseInt(att.getNodeValue())); + final int recipeId = set.getInt("id"); + List materials = Collections.emptyList(); + List productGroup = Collections.emptyList(); + List npcFee = Collections.emptyList(); + final Map statUse = new HashMap<>(); for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling()) { - if ("statUse".equalsIgnoreCase(c.getNodeName())) + if ("materials".equalsIgnoreCase(c.getNodeName())) { - final String statName = c.getAttributes().getNamedItem("name").getNodeValue(); - final int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue()); - try - { - recipeStatUseList.add(new L2RecipeStatInstance(statName, value)); - } - catch (Exception e) - { - LOGGER.severe(getClass().getSimpleName() + ": Error in StatUse parameter for recipe item id: " + id + ", skipping"); - continue RECIPES_FILE; - } + materials = getItemList(c); } - else if ("altStatChange".equalsIgnoreCase(c.getNodeName())) + else if ("product".equalsIgnoreCase(c.getNodeName())) { - final String statName = c.getAttributes().getNamedItem("name").getNodeValue(); - final int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue()); - try + productGroup = getItemList(c).stream().map(ItemChanceHolder.class::cast).collect(Collectors.toList()); + } + else if ("npcFee".equalsIgnoreCase(c.getNodeName())) + { + npcFee = getItemList(c); + } + else if ("statUse".equalsIgnoreCase(c.getNodeName())) + { + for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling()) { - recipeAltStatChangeList.add(new L2RecipeStatInstance(statName, value)); + if ("stat".equalsIgnoreCase(b.getNodeName())) + { + StatusUpdateType stat = StatusUpdateType.valueOf(b.getAttributes().getNamedItem("name").getNodeValue()); + double value = Double.parseDouble(b.getAttributes().getNamedItem("val").getNodeValue()); + statUse.put(stat, value); + } } - catch (Exception e) - { - LOGGER.severe(getClass().getSimpleName() + ": Error in AltStatChange parameter for recipe item id: " + id + ", skipping"); - continue RECIPES_FILE; - } - } - else if ("ingredient".equalsIgnoreCase(c.getNodeName())) - { - final int ingId = Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()); - final int ingCount = Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()); - recipePartList.add(new L2RecipeInstance(ingId, ingCount)); - } - else if ("production".equalsIgnoreCase(c.getNodeName())) - { - set.set("itemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue())); - set.set("count", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue())); - } - else if ("productionRare".equalsIgnoreCase(c.getNodeName())) - { - set.set("rareItemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue())); - set.set("rareCount", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue())); - set.set("rarity", Integer.parseInt(c.getAttributes().getNamedItem("rarity").getNodeValue())); - haveRare = true; } } - final L2RecipeList recipeList = new L2RecipeList(set, haveRare); - for (L2RecipeInstance recipePart : recipePartList) - { - recipeList.addRecipe(recipePart); - } - for (L2RecipeStatInstance recipeStatUse : recipeStatUseList) - { - recipeList.addStatUse(recipeStatUse); - } - for (L2RecipeStatInstance recipeAltStatChange : recipeAltStatChangeList) - { - recipeList.addAltStatChange(recipeAltStatChange); - } - - _recipes.put(id, recipeList); + _recipes.put(recipeId, new RecipeHolder(set, materials, productGroup, npcFee, statUse)); } } } } } - /** - * Gets the recipe list. - * @param listId the list id - * @return the recipe list - */ - public L2RecipeList getRecipeList(int listId) + private List getItemList(Node c) { - return _recipes.get(listId); - } - - /** - * Gets the recipe by item id. - * @param itemId the item id - * @return the recipe by item id - */ - public L2RecipeList getRecipeByItemId(int itemId) - { - for (L2RecipeList find : _recipes.values()) + final List items = new ArrayList<>(); + for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling()) { - if (find.getRecipeId() == itemId) + if ("item".equalsIgnoreCase(b.getNodeName())) { - return find; + int itemId = Integer.parseInt(b.getAttributes().getNamedItem("id").getNodeValue()); + long itemCount = Long.parseLong(b.getAttributes().getNamedItem("count").getNodeValue()); + + if (b.getAttributes().getNamedItem("chance") != null) + { + double chance = Double.parseDouble(b.getAttributes().getNamedItem("chance").getNodeValue()); + items.add(new ItemChanceHolder(itemId, chance, itemCount)); + } + else + { + items.add(new ItemHolder(itemId, itemCount)); + } } } - return null; + + return items; } /** - * Gets the all item ids. - * @return the all item ids + * Gets the recipe by recipe item id. + * @param itemId the recipe's item id + * @return {@code RecipeHolder} for the given recipe item id {@code null} if there is no recipe data connected with this recipe item id. */ - public int[] getAllItemIds() + public RecipeHolder getRecipeByRecipeItemId(int itemId) { - final int[] idList = new int[_recipes.size()]; - int i = 0; - for (L2RecipeList rec : _recipes.values()) - { - idList[i++] = rec.getRecipeId(); - } - return idList; + return _recipes.values().stream().filter(r -> r.getItemId() == itemId).findAny().orElse(null); } /** - * Gets the valid recipe list. - * @param player the player - * @param id the recipe list id - * @return the valid recipe list + * @param recipeId the id of the recipe, NOT the recipe item id. + * @return {@code RecipeHolder} containing all the info necessary for crafting a recipe or {@code null} if there is no data for this recipeId. */ - public L2RecipeList getValidRecipeList(L2PcInstance player, int id) + public RecipeHolder getRecipe(int recipeId) { - final L2RecipeList recipeList = _recipes.get(id); - if ((recipeList == null) || (recipeList.getRecipes().length == 0)) - { - player.sendMessage("No recipe for: " + id); - player.isInCraftMode(false); - return null; - } - return recipeList; + return _recipes.get(recipeId); } /** diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/engines/DocumentBase.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/engines/DocumentBase.java index 0050c0a281..6f7ebc5cf9 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/engines/DocumentBase.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/engines/DocumentBase.java @@ -74,7 +74,6 @@ import com.l2jmobius.gameserver.model.conditions.ConditionPlayerCloakStatus; import com.l2jmobius.gameserver.model.conditions.ConditionPlayerCp; import com.l2jmobius.gameserver.model.conditions.ConditionPlayerDualclass; import com.l2jmobius.gameserver.model.conditions.ConditionPlayerFlyMounted; -import com.l2jmobius.gameserver.model.conditions.ConditionPlayerGrade; import com.l2jmobius.gameserver.model.conditions.ConditionPlayerHasCastle; import com.l2jmobius.gameserver.model.conditions.ConditionPlayerHasClanHall; import com.l2jmobius.gameserver.model.conditions.ConditionPlayerHasFort; @@ -511,12 +510,6 @@ public abstract class DocumentBase cond = joinAnd(cond, new ConditionPlayerCp(cp)); break; } - case "grade": - { - final int expIndex = Integer.decode(getValue(a.getNodeValue(), template)); - cond = joinAnd(cond, new ConditionPlayerGrade(expIndex)); - break; - } case "pkcount": { final int expIndex = Integer.decode(getValue(a.getNodeValue(), template)); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/Fishing.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/Fishing.java index edbfe1412c..157a085fb2 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/Fishing.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/Fishing.java @@ -182,7 +182,7 @@ public class Fishing return; } - if (_player.isInCraftMode() || _player.isInStoreMode()) + if (_player.isCrafting() || _player.isInStoreMode()) { _player.sendPacket(SystemMessageId.YOU_CANNOT_FISH_WHILE_USING_A_RECIPE_BOOK_PRIVATE_WORKSHOP_OR_PRIVATE_STORE); _player.sendPacket(ActionFailed.STATIC_PACKET); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeInstance.java deleted file mode 100644 index 469b9843cc..0000000000 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeInstance.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.l2jmobius.gameserver.model; - -/** - * This class describes a RecipeList component (1 line of the recipe : Item-Quantity needed). - */ -public class L2RecipeInstance -{ - /** The Identifier of the item needed in the L2RecipeInstance */ - private final int _itemId; - - /** The item quantity needed in the L2RecipeInstance */ - private final int _quantity; - - /** - * Constructor of L2RecipeInstance (create a new line in a RecipeList). - * @param itemId - * @param quantity - */ - public L2RecipeInstance(int itemId, int quantity) - { - _itemId = itemId; - _quantity = quantity; - } - - /** - * @return the Identifier of the L2RecipeInstance Item needed. - */ - public int getItemId() - { - return _itemId; - } - - /** - * @return the Item quantity needed of the L2RecipeInstance. - */ - public int getQuantity() - { - return _quantity; - } - -} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeList.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeList.java deleted file mode 100644 index 672503228f..0000000000 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeList.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.l2jmobius.gameserver.model; - -/** - * This class describes a Recipe used by Dwarf to craft Item. All L2RecipeList are made of L2RecipeInstance (1 line of the recipe : Item-Quantity needed). - */ -public class L2RecipeList -{ - /** The table containing all L2RecipeInstance (1 line of the recipe : Item-Quantity needed) of the L2RecipeList */ - private L2RecipeInstance[] _recipes; - - /** The table containing all L2RecipeStatInstance for the statUse parameter of the L2RecipeList */ - private L2RecipeStatInstance[] _statUse; - - /** The table containing all L2RecipeStatInstance for the altStatChange parameter of the L2RecipeList */ - private L2RecipeStatInstance[] _altStatChange; - - /** The Identifier of the Instance */ - private final int _id; - - /** The crafting level needed to use this L2RecipeList */ - private final int _level; - - /** The Identifier of the L2RecipeList */ - private final int _recipeId; - - /** The name of the L2RecipeList */ - private final String _recipeName; - - /** The crafting success rate when using the L2RecipeList */ - private final int _successRate; - - /** The Identifier of the Item crafted with this L2RecipeList */ - private final int _itemId; - - /** The quantity of Item crafted when using this L2RecipeList */ - private final int _count; - - /** The Identifier of the Rare Item crafted with this L2RecipeList */ - private int _rareItemId; - - /** The quantity of Rare Item crafted when using this L2RecipeList */ - private int _rareCount; - - /** The chance of Rare Item crafted when using this L2RecipeList */ - private int _rarity; - - /** If this a common or a dwarven recipe */ - private final boolean _isDwarvenRecipe; - - /** - * Constructor of L2RecipeList (create a new Recipe). - * @param set - * @param haveRare - */ - public L2RecipeList(StatsSet set, boolean haveRare) - { - _recipes = new L2RecipeInstance[0]; - _statUse = new L2RecipeStatInstance[0]; - _altStatChange = new L2RecipeStatInstance[0]; - _id = set.getInt("id"); - _level = set.getInt("craftLevel"); - _recipeId = set.getInt("recipeId"); - _recipeName = set.getString("recipeName"); - _successRate = set.getInt("successRate"); - _itemId = set.getInt("itemId"); - _count = set.getInt("count"); - if (haveRare) - { - _rareItemId = set.getInt("rareItemId"); - _rareCount = set.getInt("rareCount"); - _rarity = set.getInt("rarity"); - } - _isDwarvenRecipe = set.getBoolean("isDwarvenRecipe"); - } - - /** - * Add a L2RecipeInstance to the L2RecipeList (add a line Item-Quantity needed to the Recipe). - * @param recipe - */ - public void addRecipe(L2RecipeInstance recipe) - { - final int len = _recipes.length; - final L2RecipeInstance[] tmp = new L2RecipeInstance[len + 1]; - System.arraycopy(_recipes, 0, tmp, 0, len); - tmp[len] = recipe; - _recipes = tmp; - } - - /** - * Add a L2RecipeStatInstance of the statUse parameter to the L2RecipeList. - * @param statUse - */ - public void addStatUse(L2RecipeStatInstance statUse) - { - final int len = _statUse.length; - final L2RecipeStatInstance[] tmp = new L2RecipeStatInstance[len + 1]; - System.arraycopy(_statUse, 0, tmp, 0, len); - tmp[len] = statUse; - _statUse = tmp; - } - - /** - * Add a L2RecipeStatInstance of the altStatChange parameter to the L2RecipeList. - * @param statChange - */ - public void addAltStatChange(L2RecipeStatInstance statChange) - { - final int len = _altStatChange.length; - final L2RecipeStatInstance[] tmp = new L2RecipeStatInstance[len + 1]; - System.arraycopy(_altStatChange, 0, tmp, 0, len); - tmp[len] = statChange; - _altStatChange = tmp; - } - - /** - * @return the Identifier of the Instance. - */ - public int getId() - { - return _id; - } - - /** - * @return the crafting level needed to use this L2RecipeList. - */ - public int getLevel() - { - return _level; - } - - /** - * @return the Identifier of the L2RecipeList. - */ - public int getRecipeId() - { - return _recipeId; - } - - /** - * @return the name of the L2RecipeList. - */ - public String getRecipeName() - { - return _recipeName; - } - - /** - * @return the crafting success rate when using the L2RecipeList. - */ - public int getSuccessRate() - { - return _successRate; - } - - /** - * @return the Identifier of the Item crafted with this L2RecipeList. - */ - public int getItemId() - { - return _itemId; - } - - /** - * @return the quantity of Item crafted when using this L2RecipeList. - */ - public int getCount() - { - return _count; - } - - /** - * @return the Identifier of the Rare Item crafted with this L2RecipeList. - */ - public int getRareItemId() - { - return _rareItemId; - } - - /** - * @return the quantity of Rare Item crafted when using this L2RecipeList. - */ - public int getRareCount() - { - return _rareCount; - } - - /** - * @return the chance of Rare Item crafted when using this L2RecipeList. - */ - public int getRarity() - { - return _rarity; - } - - /** - * @return {@code true} if this a Dwarven recipe or {@code false} if its a Common recipe - */ - public boolean isDwarvenRecipe() - { - return _isDwarvenRecipe; - } - - /** - * @return the table containing all L2RecipeInstance (1 line of the recipe : Item-Quantity needed) of the L2RecipeList. - */ - public L2RecipeInstance[] getRecipes() - { - return _recipes; - } - - /** - * @return the table containing all L2RecipeStatInstance of the statUse parameter of the L2RecipeList. - */ - public L2RecipeStatInstance[] getStatUse() - { - return _statUse; - } - - /** - * @return the table containing all L2RecipeStatInstance of the AltStatChange parameter of the L2RecipeList. - */ - public L2RecipeStatInstance[] getAltStatChange() - { - return _altStatChange; - } -} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeStatInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeStatInstance.java deleted file mode 100644 index ae06fa8c1b..0000000000 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2RecipeStatInstance.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.l2jmobius.gameserver.model; - -import com.l2jmobius.gameserver.enums.StatType; - -/** - * This class describes a RecipeList statUse and altStatChange component. - */ -public class L2RecipeStatInstance -{ - /** The Identifier of the statType */ - private final StatType _type; - - /** The value of the statType */ - private final int _value; - - /** - * Constructor of L2RecipeStatInstance. - * @param type - * @param value - */ - public L2RecipeStatInstance(String type, int value) - { - _type = Enum.valueOf(StatType.class, type); - _value = value; - } - - /** - * @return the the type of the L2RecipeStatInstance. - */ - public StatType getType() - { - return _type; - } - - /** - * @return the value of the L2RecipeStatInstance. - */ - public int getValue() - { - return _value; - } - -} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2Seed.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2Seed.java index ced8554e47..e099179153 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2Seed.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/L2Seed.java @@ -32,8 +32,8 @@ public final class L2Seed private final boolean _isAlternative; private final int _limitSeeds; private final int _limitCrops; - private final int _seedReferencePrice; - private final int _cropReferencePrice; + private final long _seedReferencePrice; + private final long _cropReferencePrice; public L2Seed(StatsSet set) { @@ -99,27 +99,27 @@ public final class L2Seed return _limitCrops * Config.RATE_DROP_MANOR; } - public final int getSeedReferencePrice() + public final long getSeedReferencePrice() { return _seedReferencePrice; } - public final int getSeedMaxPrice() + public final long getSeedMaxPrice() { return _seedReferencePrice * 10; } - public final int getSeedMinPrice() + public final long getSeedMinPrice() { return (int) (_seedReferencePrice * 0.6); } - public final int getCropReferencePrice() + public final long getCropReferencePrice() { return _cropReferencePrice; } - public final int getCropMaxPrice() + public final long getCropMaxPrice() { return _cropReferencePrice * 10; } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/TempItem.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/TempItem.java index fa918cfc55..db4b2f817f 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/TempItem.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/TempItem.java @@ -28,7 +28,7 @@ public final class TempItem { private final int _itemId; private int _quantity; - private final int _referencePrice; + private final long _referencePrice; private final String _itemName; /** @@ -60,7 +60,7 @@ public final class TempItem _quantity = quantity; } - public int getReferencePrice() + public long getReferencePrice() { return _referencePrice; } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 77605ef09b..32f9b286f2 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -27,7 +27,6 @@ import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -46,11 +45,11 @@ import java.util.stream.Collectors; import com.l2jmobius.Config; import com.l2jmobius.commons.database.DatabaseFactory; +import com.l2jmobius.commons.util.CommonUtil; import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.ItemsAutoDestroy; import com.l2jmobius.gameserver.LoginServerThread; -import com.l2jmobius.gameserver.RecipeController; import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.ai.CtrlIntention; import com.l2jmobius.gameserver.ai.L2CharacterAI; @@ -63,6 +62,7 @@ import com.l2jmobius.gameserver.data.sql.impl.CharNameTable; import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable; import com.l2jmobius.gameserver.data.sql.impl.ClanTable; import com.l2jmobius.gameserver.data.xml.impl.AdminData; +import com.l2jmobius.gameserver.data.xml.impl.CategoryData; import com.l2jmobius.gameserver.data.xml.impl.ClassListData; import com.l2jmobius.gameserver.data.xml.impl.ExperienceData; import com.l2jmobius.gameserver.data.xml.impl.HennaData; @@ -85,6 +85,7 @@ import com.l2jmobius.gameserver.enums.GroupType; import com.l2jmobius.gameserver.enums.HtmlActionScope; import com.l2jmobius.gameserver.enums.IllegalActionPunishmentType; import com.l2jmobius.gameserver.enums.InstanceType; +import com.l2jmobius.gameserver.enums.ItemGrade; import com.l2jmobius.gameserver.enums.MountType; import com.l2jmobius.gameserver.enums.NextActionType; import com.l2jmobius.gameserver.enums.PartyDistributionType; @@ -116,6 +117,7 @@ import com.l2jmobius.gameserver.instancemanager.MatchingRoomManager; import com.l2jmobius.gameserver.instancemanager.MentorManager; import com.l2jmobius.gameserver.instancemanager.PunishmentManager; import com.l2jmobius.gameserver.instancemanager.QuestManager; +import com.l2jmobius.gameserver.instancemanager.SellBuffsManager; import com.l2jmobius.gameserver.instancemanager.SiegeManager; import com.l2jmobius.gameserver.instancemanager.ZoneManager; import com.l2jmobius.gameserver.model.ArenaParticipantsHolder; @@ -128,7 +130,6 @@ import com.l2jmobius.gameserver.model.L2Clan; import com.l2jmobius.gameserver.model.L2ClanMember; import com.l2jmobius.gameserver.model.L2CommandChannel; import com.l2jmobius.gameserver.model.L2ContactList; -import com.l2jmobius.gameserver.model.L2ManufactureItem; import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Party; import com.l2jmobius.gameserver.model.L2Party.MessageType; @@ -136,7 +137,6 @@ import com.l2jmobius.gameserver.model.L2PetData; import com.l2jmobius.gameserver.model.L2PetLevelData; import com.l2jmobius.gameserver.model.L2PremiumItem; import com.l2jmobius.gameserver.model.L2Radar; -import com.l2jmobius.gameserver.model.L2RecipeList; import com.l2jmobius.gameserver.model.L2Request; import com.l2jmobius.gameserver.model.L2SkillLearn; import com.l2jmobius.gameserver.model.L2World; @@ -163,7 +163,6 @@ import com.l2jmobius.gameserver.model.actor.stat.PcStat; import com.l2jmobius.gameserver.model.actor.status.PcStatus; import com.l2jmobius.gameserver.model.actor.tasks.player.DismountTask; import com.l2jmobius.gameserver.model.actor.tasks.player.FameTask; -import com.l2jmobius.gameserver.model.actor.tasks.player.GameGuardCheckTask; import com.l2jmobius.gameserver.model.actor.tasks.player.HennaDurationTask; import com.l2jmobius.gameserver.model.actor.tasks.player.InventoryEnableTask; import com.l2jmobius.gameserver.model.actor.tasks.player.PetFeedTask; @@ -180,8 +179,6 @@ import com.l2jmobius.gameserver.model.actor.tasks.player.WaterTask; import com.l2jmobius.gameserver.model.actor.templates.L2PcTemplate; import com.l2jmobius.gameserver.model.actor.transform.Transform; import com.l2jmobius.gameserver.model.base.ClassId; -import com.l2jmobius.gameserver.model.base.ClassLevel; -import com.l2jmobius.gameserver.model.base.PlayerClass; import com.l2jmobius.gameserver.model.base.SubClass; import com.l2jmobius.gameserver.model.ceremonyofchaos.CeremonyOfChaosEvent; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -215,6 +212,7 @@ import com.l2jmobius.gameserver.model.holders.MonsterBookCardHolder; import com.l2jmobius.gameserver.model.holders.MonsterBookRewardHolder; import com.l2jmobius.gameserver.model.holders.MovieHolder; import com.l2jmobius.gameserver.model.holders.PlayerEventHolder; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.model.holders.SellBuffHolder; import com.l2jmobius.gameserver.model.holders.SkillUseHolder; import com.l2jmobius.gameserver.model.holders.TrainingHolder; @@ -235,6 +233,7 @@ import com.l2jmobius.gameserver.model.items.L2Weapon; import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.model.items.type.ActionType; import com.l2jmobius.gameserver.model.items.type.ArmorType; +import com.l2jmobius.gameserver.model.items.type.CrystalType; import com.l2jmobius.gameserver.model.items.type.EtcItemType; import com.l2jmobius.gameserver.model.items.type.WeaponType; import com.l2jmobius.gameserver.model.matching.MatchingRoom; @@ -293,7 +292,6 @@ import com.l2jmobius.gameserver.network.serverpackets.ExUseSharedGroupItem; import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoAbnormalVisualEffect; import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoCubic; import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight; -import com.l2jmobius.gameserver.network.serverpackets.GameGuardQuery; import com.l2jmobius.gameserver.network.serverpackets.GetOnVehicle; import com.l2jmobius.gameserver.network.serverpackets.HennaInfo; import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket; @@ -523,13 +521,13 @@ public final class L2PcInstance extends L2Playable private AdminTeleportType _teleportType = AdminTeleportType.NORMAL; private boolean _inCrystallize; - private boolean _inCraftMode; + private volatile boolean _isCrafting; private long _offlineShopStart = 0; /** The table containing all L2RecipeList of the L2PcInstance */ - private final Map _dwarvenRecipeBook = new ConcurrentSkipListMap<>(); - private final Map _commonRecipeBook = new ConcurrentSkipListMap<>(); + private final Map _dwarvenRecipeBook = new ConcurrentSkipListMap<>(); + private final Map _commonRecipeBook = new ConcurrentSkipListMap<>(); /** Premium Items */ private final Map _premiumItems = new ConcurrentSkipListMap<>(); @@ -564,7 +562,7 @@ public final class L2PcInstance extends L2Playable private TradeList _activeTradeList; private ItemContainer _activeWarehouse; - private volatile Map _manufactureItems; + private volatile Map _manufactureItems; private String _storeName = ""; private TradeList _sellList; private TradeList _buyList; @@ -619,8 +617,6 @@ public final class L2PcInstance extends L2Playable // after Freya players can control more than one tamed beast private volatile Set _tamedBeast = null; - private boolean _minimapAllowed = false; - // client radar // TODO: This needs to be better integrated and saved/loaded private final L2Radar _radar; @@ -712,6 +708,10 @@ public final class L2PcInstance extends L2Playable // private byte _updateKnownCounter = 0; + private int _createItemLevel; + private int _createCommonItemLevel; + private ItemGrade _crystallizeGrade = ItemGrade.NONE; + private CrystalType _expertiseLevel = CrystalType.NONE; private int _expertiseArmorPenalty = 0; private int _expertiseWeaponPenalty = 0; private int _expertisePenaltyBonus = 0; @@ -1259,14 +1259,14 @@ public final class L2PcInstance extends L2Playable return getPrivateStoreType() != PrivateStoreType.NONE; } - public boolean isInCraftMode() + public boolean isCrafting() { - return _inCraftMode; + return _isCrafting; } - public void isInCraftMode(boolean b) + public void setIsCrafting(boolean isCrafting) { - _inCraftMode = b; + _isCrafting = isCrafting; } /** @@ -1304,17 +1304,17 @@ public final class L2PcInstance extends L2Playable /** * @return a table containing all Common L2RecipeList of the L2PcInstance. */ - public L2RecipeList[] getCommonRecipeBook() + public Collection getCommonRecipeBook() { - return _commonRecipeBook.values().toArray(new L2RecipeList[_commonRecipeBook.values().size()]); + return _commonRecipeBook.values(); } /** * @return a table containing all Dwarf L2RecipeList of the L2PcInstance. */ - public L2RecipeList[] getDwarvenRecipeBook() + public Collection getDwarvenRecipeBook() { - return _dwarvenRecipeBook.values().toArray(new L2RecipeList[_dwarvenRecipeBook.values().size()]); + return _dwarvenRecipeBook.values(); } /** @@ -1322,7 +1322,7 @@ public final class L2PcInstance extends L2Playable * @param recipe The L2RecipeList to add to the _recipebook * @param saveToDb */ - public void registerCommonRecipeList(L2RecipeList recipe, boolean saveToDb) + public void registerCommonRecipeList(RecipeHolder recipe, boolean saveToDb) { _commonRecipeBook.put(recipe.getId(), recipe); @@ -1337,7 +1337,7 @@ public final class L2PcInstance extends L2Playable * @param recipe The L2RecipeList to add to the _recipebook * @param saveToDb */ - public void registerDwarvenRecipeList(L2RecipeList recipe, boolean saveToDb) + public void registerDwarvenRecipeList(RecipeHolder recipe, boolean saveToDb) { _dwarvenRecipeBook.put(recipe.getId(), recipe); @@ -1867,29 +1867,39 @@ public final class L2PcInstance extends L2Playable } /** - * @return True if the L2PcInstance can Craft Dwarven Recipes. + * @return the maximum dwarven recipe level this character can craft. */ - public boolean hasDwarvenCraft() + public int getCreateItemLevel() { - return getSkillLevel(CommonSkill.CREATE_DWARVEN.getId()) >= 1; + return _createItemLevel; } - public int getDwarvenCraft() + public void setCreateItemLevel(int createItemLevel) { - return getSkillLevel(CommonSkill.CREATE_DWARVEN.getId()); + _createItemLevel = createItemLevel; } /** - * @return True if the L2PcInstance can Craft Dwarven Recipes. + * @return the maximum common recipe level this character can craft. */ - public boolean hasCommonCraft() + public int getCreateCommonItemLevel() { - return getSkillLevel(CommonSkill.CREATE_COMMON.getId()) >= 1; + return _createCommonItemLevel; } - public int getCommonCraft() + public void setCreateCommonItemLevel(int createCommonItemLevel) { - return getSkillLevel(CommonSkill.CREATE_COMMON.getId()); + _createCommonItemLevel = createCommonItemLevel; + } + + public ItemGrade getCrystallizeGrade() + { + return _crystallizeGrade; + } + + public void setCrystallizeGrade(ItemGrade crystallizeGrade) + { + _crystallizeGrade = crystallizeGrade != null ? crystallizeGrade : ItemGrade.NONE; } /** @@ -2073,11 +2083,7 @@ public final class L2PcInstance extends L2Playable public int getWeightPenalty() { - if (_dietMode) - { - return 0; - } - return _curWeightPenalty; + return _dietMode ? 0 : _curWeightPenalty; } /** @@ -2141,37 +2147,26 @@ public final class L2PcInstance extends L2Playable return; } - final int expertiseLevel = getExpertiseLevel(); + final CrystalType expertiseLevel = getExpertiseLevel().plusLevel(getExpertisePenaltyBonus()); int armorPenalty = 0; int weaponPenalty = 0; - int crystaltype; - for (L2ItemInstance item : getInventory().getItems()) + for (L2ItemInstance item : getInventory().getPaperdollItems(item -> (item != null) && ((item.getItemType() != EtcItemType.ARROW) && (item.getItemType() != EtcItemType.BOLT)) && item.getItem().getCrystalType().isGreater(expertiseLevel))) { - if ((item != null) && item.isEquipped() && ((item.getItemType() != EtcItemType.ARROW) && (item.getItemType() != EtcItemType.BOLT))) + if (item.isArmor()) { - crystaltype = item.getItem().getCrystalType().getId(); - if (crystaltype > expertiseLevel) - { - if (item.isWeapon() && (crystaltype > weaponPenalty)) - { - weaponPenalty = crystaltype; - } - else if (crystaltype > armorPenalty) - { - armorPenalty = crystaltype; - } - } + // Armor penalty level increases depending on amount of penalty armors equipped, not grade level difference. + armorPenalty = CommonUtil.constrain(armorPenalty + 1, 0, 4); + } + else + { + // Weapon penalty level increases based on grade difference. + weaponPenalty = CommonUtil.constrain(item.getItem().getCrystalType().getLevel() - expertiseLevel.getLevel(), 0, 4); } } boolean changed = false; - final int bonus = getExpertisePenaltyBonus(); - - // calc weapon penalty - weaponPenalty = weaponPenalty - expertiseLevel - bonus; - weaponPenalty = Math.min(Math.max(weaponPenalty, 0), 4); if ((getExpertiseWeaponPenalty() != weaponPenalty) || (getSkillLevel(CommonSkill.WEAPON_GRADE_PENALTY.getId()) != weaponPenalty)) { @@ -2182,15 +2177,11 @@ public final class L2PcInstance extends L2Playable } else { - removeSkill(getKnownSkill(CommonSkill.WEAPON_GRADE_PENALTY.getId()), false, true); + removeSkill(CommonSkill.WEAPON_GRADE_PENALTY.getId(), true); } changed = true; } - // calc armor penalty - armorPenalty = armorPenalty - expertiseLevel - bonus; - armorPenalty = Math.min(Math.max(armorPenalty, 0), 4); - if ((getExpertiseArmorPenalty() != armorPenalty) || (getSkillLevel(CommonSkill.ARMOR_GRADE_PENALTY.getId()) != armorPenalty)) { _expertiseArmorPenalty = armorPenalty; @@ -2200,13 +2191,14 @@ public final class L2PcInstance extends L2Playable } else { - removeSkill(getKnownSkill(CommonSkill.ARMOR_GRADE_PENALTY.getId()), false, true); + removeSkill(CommonSkill.ARMOR_GRADE_PENALTY.getId(), true); } changed = true; } if (changed) { + sendSkillList(); // Update expertise penalty icon in skill list. sendPacket(new EtcStatusUpdate(this)); } } @@ -2383,7 +2375,7 @@ public final class L2PcInstance extends L2Playable try { - if ((getLvlJoinedAcademy() != 0) && (_clan != null) && (PlayerClass.values()[Id].getLevel() == ClassLevel.THIRD)) + if ((getLvlJoinedAcademy() != 0) && (_clan != null) && CategoryData.getInstance().isInCategory(CategoryType.THIRD_CLASS_GROUP, Id)) { if (getLvlJoinedAcademy() <= 16) { @@ -2416,7 +2408,7 @@ public final class L2PcInstance extends L2Playable setTarget(this); broadcastPacket(new MagicSkillUse(this, 5103, 1, 1000, 0)); setClassTemplate(Id); - if (getClassId().level() == 3) + if (isInCategory(CategoryType.FOURTH_CLASS_GROUP)) { sendPacket(SystemMessageId.CONGRATULATIONS_YOU_VE_COMPLETED_YOUR_THIRD_CLASS_TRANSFER_QUEST); } @@ -2710,18 +2702,6 @@ public final class L2PcInstance extends L2Playable return _radar; } - /* Return true if Hellbound minimap allowed */ - public boolean isMinimapAllowed() - { - return _minimapAllowed; - } - - /* Enable or disable minimap on Hellbound */ - public void setMinimapAllowed(boolean b) - { - _minimapAllowed = b; - } - /** * @return the SP amount of the L2PcInstance. */ @@ -4355,6 +4335,8 @@ public final class L2PcInstance extends L2Playable return getClan().getAllyCrestId(); } + //@formatter:off + /* public void queryGameGuard() { if (getClient() != null) @@ -4364,9 +4346,10 @@ public final class L2PcInstance extends L2Playable } if (Config.GAMEGUARD_ENFORCE) { - ThreadPoolManager.schedule(new GameGuardCheckTask(this), 30 * 1000); + ThreadPool.scheduleGeneral(new GameGuardCheckTask(this), 30 * 1000); } - } + }*/ + //@formatter:on /** * Send a Server->Client packet StatusUpdate to the L2PcInstance. @@ -4404,22 +4387,28 @@ public final class L2PcInstance extends L2Playable { if (target instanceof L2PcInstance) { - final L2PcInstance temp = (L2PcInstance) target; + final L2PcInstance targetPlayer = (L2PcInstance) target; sendPacket(ActionFailed.STATIC_PACKET); - if ((temp.getPrivateStoreType() == PrivateStoreType.SELL) || (temp.getPrivateStoreType() == PrivateStoreType.PACKAGE_SELL)) + if ((targetPlayer.getPrivateStoreType() == PrivateStoreType.SELL) || (targetPlayer.getPrivateStoreType() == PrivateStoreType.PACKAGE_SELL)) { - sendPacket(new PrivateStoreListSell(this, temp)); + if (isSellingBuffs()) + { + SellBuffsManager.getInstance().sendBuffMenu(this, targetPlayer, 0); + } + else + { + sendPacket(new PrivateStoreListSell(this, targetPlayer)); + } } - else if (temp.getPrivateStoreType() == PrivateStoreType.BUY) + else if (targetPlayer.getPrivateStoreType() == PrivateStoreType.BUY) { - sendPacket(new PrivateStoreListBuy(this, temp)); + sendPacket(new PrivateStoreListBuy(this, targetPlayer)); } - else if (temp.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) + else if (targetPlayer.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) { - sendPacket(new RecipeShopSellList(this, temp)); + sendPacket(new RecipeShopSellList(this, targetPlayer)); } - } else if (target != null) // _interactTarget=null should never happen but one never knows ^^; { @@ -5057,6 +5046,9 @@ public final class L2PcInstance extends L2Playable // Clear resurrect xp calculation setExpBeforeDeath(0); + // Calculate Shilen's Breath debuff level. It must happen right before death, because buffs aren't applied on dead characters. + calculateShilensBreathDebuffLevel(killer); + // Kill the L2PcInstance if (!super.doDie(killer)) { @@ -5110,9 +5102,6 @@ public final class L2PcInstance extends L2Playable } } - // calculate Shilen's Breath debuff level - calculateShilensBreathDebuffLevel(killer); - if (isMounted()) { stopFeed(); @@ -5778,21 +5767,21 @@ public final class L2PcInstance extends L2Playable * Get the manufacture items map of this player. * @return the the manufacture items map */ - public Map getManufactureItems() + public Map getManufactureItems() { if (_manufactureItems == null) { - synchronized (this) - { - if (_manufactureItems == null) - { - _manufactureItems = Collections.synchronizedMap(new LinkedHashMap<>()); - } - } + return Collections.emptyMap(); } + return _manufactureItems; } + public void setManufactureItems(Map manufactureItems) + { + _manufactureItems = manufactureItems; + } + /** * Get the store name, if any. * @return the store name @@ -6524,7 +6513,7 @@ public final class L2PcInstance extends L2Playable statement.setInt(23, getRace().ordinal()); statement.setInt(24, getClassId().getId()); statement.setLong(25, getDeleteTimer()); - statement.setInt(26, hasDwarvenCraft() ? 1 : 0); + statement.setInt(26, getCreateItemLevel() > 0 ? 1 : 0); statement.setString(27, getTitle()); statement.setInt(28, getAppearance().getTitleColor()); statement.setInt(29, isOnlineInt()); @@ -6994,11 +6983,11 @@ public final class L2PcInstance extends L2Playable { _dwarvenRecipeBook.clear(); - L2RecipeList recipe; - final RecipeData rd = RecipeData.getInstance(); + RecipeHolder recipe; + RecipeData rd = RecipeData.getInstance(); while (rset.next()) { - recipe = rd.getRecipeList(rset.getInt("id")); + recipe = rd.getRecipe(rset.getInt("id")); if (loadCommon) { if (rset.getInt(2) == 1) @@ -8770,7 +8759,7 @@ public final class L2PcInstance extends L2Playable { for (int itemId : _activeSoulShots) { - if (ItemTable.getInstance().getTemplate(itemId).getCrystalType().getId() == crystalType) + if (ItemTable.getInstance().getTemplate(itemId).getCrystalType().getLevel() == crystalType) { disableAutoShot(itemId); } @@ -10290,17 +10279,17 @@ public final class L2PcInstance extends L2Playable } /** - * Expertise of the L2PcInstance (None=0, D=1, C=2, B=3, A=4, S=5, S80=6, S84=7) - * @return int Expertise skill level. + * Expertise of the L2PcInstance (None=0, D=1, C=2, B=3, A=4, S=5, S80=6, S84=7, R=8, R95=9, R99=10) + * @return CrystalTyperepresenting expertise level.. */ - public int getExpertiseLevel() + public CrystalType getExpertiseLevel() { - int level = getSkillLevel(239); - if (level < 0) - { - level = 0; - } - return level; + return _expertiseLevel; + } + + public void setExpertiseLevel(CrystalType crystalType) + { + _expertiseLevel = crystalType != null ? crystalType : CrystalType.NONE; } @Override @@ -10864,16 +10853,6 @@ public final class L2PcInstance extends L2Playable _log.log(Level.SEVERE, "deleteMe()", e); } - // Stop crafting, if in progress - try - { - RecipeController.getInstance().requestMakeItemAbort(this); - } - catch (Exception e) - { - _log.log(Level.SEVERE, "deleteMe()", e); - } - // Cancel Attak or Cast try { @@ -12501,11 +12480,11 @@ public final class L2PcInstance extends L2Playable { final AtomicInteger slot = new AtomicInteger(1); con.setAutoCommit(false); - for (L2ManufactureItem item : _manufactureItems.values()) + for (Entry entry : _manufactureItems.entrySet()) { st.setInt(1, getObjectId()); - st.setInt(2, item.getRecipeId()); - st.setLong(3, item.getCost()); + st.setInt(2, entry.getKey()); + st.setLong(3, entry.getValue()); st.setInt(4, slot.getAndIncrement()); st.addBatch(); } @@ -12522,10 +12501,7 @@ public final class L2PcInstance extends L2Playable private void restoreRecipeShopList() { - if (_manufactureItems != null) - { - _manufactureItems.clear(); - } + final Map manufactureItems = new HashMap<>(); try (Connection con = DatabaseFactory.getInstance().getConnection(); PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_RECIPE_SHOP)) @@ -12535,7 +12511,7 @@ public final class L2PcInstance extends L2Playable { while (rset.next()) { - getManufactureItems().put(rset.getInt("recipeId"), new L2ManufactureItem(rset.getInt("recipeId"), rset.getLong("price"))); + manufactureItems.put(rset.getInt("recipeId"), rset.getLong("price")); } } } @@ -12543,6 +12519,8 @@ public final class L2PcInstance extends L2Playable { _log.log(Level.SEVERE, "Could not restore recipe shop list data for playerId: " + getObjectId(), e); } + + _manufactureItems = manufactureItems; } @Override diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/status/PcStatus.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/status/PcStatus.java index a97eab382d..dcb3ab34da 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/status/PcStatus.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/status/PcStatus.java @@ -78,7 +78,7 @@ public class PcStatus extends PlayableStatus } // If OFFLINE_MODE_NO_DAMAGE is enabled and player is offline and he is in store/craft mode, no damage is taken. - if (Config.OFFLINE_MODE_NO_DAMAGE && (getActiveChar().getClient() != null) && getActiveChar().getClient().isDetached() && ((Config.OFFLINE_TRADE_ENABLE && ((getActiveChar().getPrivateStoreType() == PrivateStoreType.SELL) || (getActiveChar().getPrivateStoreType() == PrivateStoreType.BUY))) || (Config.OFFLINE_CRAFT_ENABLE && (getActiveChar().isInCraftMode() || (getActiveChar().getPrivateStoreType() == PrivateStoreType.MANUFACTURE))))) + if (Config.OFFLINE_MODE_NO_DAMAGE && (getActiveChar().getClient() != null) && getActiveChar().getClient().isDetached() && ((Config.OFFLINE_TRADE_ENABLE && ((getActiveChar().getPrivateStoreType() == PrivateStoreType.SELL) || (getActiveChar().getPrivateStoreType() == PrivateStoreType.BUY))) || (Config.OFFLINE_CRAFT_ENABLE && (getActiveChar().isCrafting() || (getActiveChar().getPrivateStoreType() == PrivateStoreType.MANUFACTURE))))) { return; } @@ -100,7 +100,7 @@ public class PcStatus extends PlayableStatus getActiveChar().stopEffectsOnDamage(); } // Attacked players in craft/shops stand up. - if (getActiveChar().isInCraftMode() || getActiveChar().isInStoreMode()) + if (getActiveChar().isCrafting() || getActiveChar().isInStoreMode()) { getActiveChar().setPrivateStoreType(PrivateStoreType.NONE); getActiveChar().standUp(); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerGrade.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerGrade.java deleted file mode 100644 index 8d2e52b55c..0000000000 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/conditions/ConditionPlayerGrade.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the L2J Mobius project. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.l2jmobius.gameserver.model.conditions; - -import java.util.logging.Logger; - -import com.l2jmobius.gameserver.model.actor.L2Character; -import com.l2jmobius.gameserver.model.items.L2Item; -import com.l2jmobius.gameserver.model.skills.Skill; - -/** - * The Class ConditionPlayerGrade. - * @author Gigiikun - */ -public final class ConditionPlayerGrade extends Condition -{ - protected static final Logger _log = Logger.getLogger(ConditionPlayerGrade.class.getName()); - // conditional values - public static final int COND_NO_GRADE = 0x0001; - public static final int COND_D_GRADE = 0x0002; - public static final int COND_C_GRADE = 0x0004; - public static final int COND_B_GRADE = 0x0008; - public static final int COND_A_GRADE = 0x0010; - public static final int COND_S_GRADE = 0x0020; - public static final int COND_S80_GRADE = 0x0040; - public static final int COND_S84_GRADE = 0x0080; - - private final int _value; - - /** - * Instantiates a new condition player grade. - * @param value the value - */ - public ConditionPlayerGrade(int value) - { - _value = value; - } - - /** - * - */ - @Override - public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item) - { - return (effector.getActingPlayer() != null) && (_value == (byte) effector.getActingPlayer().getExpertiseLevel()); - } -} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/RecipeHolder.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/RecipeHolder.java new file mode 100644 index 0000000000..5e33d6f797 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/holders/RecipeHolder.java @@ -0,0 +1,336 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.gameserver.model.holders; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.enums.StatusUpdateType; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.interfaces.IIdentifiable; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; + +/** + * A holder representing a craftable recipe based on the former L2RecipeList.
+ * It contains all the recipe data and methods required for crafting this recipe. + * @author Nik + */ +public class RecipeHolder implements IIdentifiable +{ + /** List of materials required to craft this recipe. */ + private final List _materials; + + /** Group of products where a single product will randomly be selected upon crafting. */ + private final List _productGroup; + + private final List _npcFee; + + /** Stats and amount required to perform the craft. */ + private final Map _statUse; + + private final int _id; + private final int _level; + private final int _itemId; + private final String _name; + private final double _successRate; + private final boolean _isCommonRecipe; + private final double _maxOfferingBonus; + private final long _maxOffering; + + public RecipeHolder(StatsSet set, List ingredients, List productGroup, List npcFee, Map statUse) + { + _id = set.getInt("id"); + _level = set.getInt("level"); + _itemId = set.getInt("itemId"); + _name = set.getString("name"); + _successRate = set.getDouble("successRate"); + _isCommonRecipe = set.getBoolean("isCommonRecipe"); + _maxOfferingBonus = set.getDouble("maxOfferingBonus", Math.max(0, 100 - _successRate)); + _maxOffering = set.getLong("maxOffering", 0); + + _materials = Collections.unmodifiableList(ingredients); + _productGroup = Collections.unmodifiableList(productGroup); + _npcFee = Collections.unmodifiableList(npcFee); + _statUse = Collections.unmodifiableMap(statUse); + } + + /** + * @return the recipe id, NOT the recipe's item id + */ + @Override + public int getId() + { + return _id; + } + + /** + * @return the crafting level needed to use this L2RecipeList. + */ + public int getLevel() + { + return _level; + } + + /** + * @return the recipe's item id. + */ + public int getItemId() + { + return _itemId; + } + + /** + * @return the name of the L2RecipeList. + */ + public String getName() + { + return _name; + } + + /** + * @return the crafting success rate when using the L2RecipeList. + */ + public double getSuccessRate() + { + return _successRate; + } + + /** + * @return {@code true} if this a Dwarven recipe or {@code false} if its a Common recipe + */ + public boolean isDwarvenRecipe() + { + return !_isCommonRecipe; + } + + /** + * @return list of materials required to complete the recipe. + */ + public List getMaterials() + { + return _materials; + } + + /** + * @return the whole group of products from which one random item will result in being crafted. + */ + public List getProductGroup() + { + return _productGroup; + } + + /** + * @return list of items that NPCs take for crafting this recipe. + */ + public List getNpcFee() + { + return _npcFee; + } + + /** + * @return the table containing all L2RecipeStatInstance of the statUse parameter of the L2RecipeList. + */ + public Map getStatUse() + { + return _statUse; + } + + /** + * @return Maximum bonus success rate when maximum offering is reached. Default is the rate needed to reach 100% success rate. + */ + public double getMaxOfferingBonus() + { + return _maxOfferingBonus; + } + + /** + * @return Maximum amount of items' adena worth offering. {@code 0} if this recipe does not allow offering. + */ + public long getMaxOffering() + { + return _maxOffering; + } + + /** + * Picks a random number then attempts to get a product from the group based on it. + * @return {@code ItemChanceHolder} that is the randomly picked product from the group,
+ * or {@code null} if the whole chance sum of the products in the group didn't manage to outnumber the random. + */ + public ItemChanceHolder getRandomProduct() + { + double random = Rnd.get(100); + for (ItemChanceHolder product : _productGroup) + { + if (product.getChance() > random) + { + return product; + } + + random -= product.getChance(); + } + + return null; + } + + public boolean checkNecessaryStats(L2PcInstance player, L2PcInstance manufacturer, boolean sendMessage) + { + for (Entry entry : _statUse.entrySet()) + { + final StatusUpdateType stat = entry.getKey(); + final double requiredAmount = entry.getValue(); + + // Less than or equals to because some stats bad interraction - like HP could kill the player if its taken all. + if (stat.getValue(manufacturer) <= requiredAmount) + { + if (sendMessage) + { + switch (stat) + { + case CUR_HP: + { + player.sendPacket(SystemMessageId.NOT_ENOUGH_HP); + break; + } + case CUR_MP: + { + player.sendPacket(SystemMessageId.NOT_ENOUGH_MP); + break; + } + default: + { + player.sendMessage("You need " + requiredAmount + " " + stat.toString().toLowerCase() + " to perform this craft."); + break; + } + } + } + + return false; + } + } + return true; + } + + /** + * @param player the player's inventory to check. + * @param sendMessage send system messages for item requirements if there is missing ingredient. + * @return {@code true} if all necessary ingredients are met, {@code false} if there are missing ingredients. + */ + public boolean checkNecessaryIngredients(L2PcInstance player, boolean sendMessage) + { + for (ItemHolder ingredient : getMaterials()) + { + final long count = player.getInventory().getInventoryItemCount(ingredient.getId(), -1); + if (count < ingredient.getCount()) + { + if (sendMessage) + { + final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_NEED_S2_MORE_S1_S); + sm.addItemName(ingredient.getId()); + sm.addLong(ingredient.getCount() - count); + player.sendPacket(sm); + } + + return false; + } + } + + return true; + } + + /** + * @param player the player requesting the craft. + * @param manufacturer the player doing the craft (either the same player or manufacture shop). + * @param success {@code true} to give the product item to the player, {@code false} otherwise. + * @param craftingCritical {@code true} to give double of the product (if success), {@code false} otherwise. + * @param sendMessage send system messages of the process. + * @return {@code ItemHolder} of the randomly created product (even if its failing craft), {@code null} if the item creation was not performed due to failed checks. + */ + public ItemHolder doCraft(L2PcInstance player, L2PcInstance manufacturer, boolean success, boolean craftingCritical, boolean sendMessage) + { + if (!checkNecessaryStats(player, manufacturer, sendMessage)) + { + return null; + } + + if (!checkNecessaryIngredients(player, sendMessage)) + { + return null; + } + + // Take necessary stats. + for (Entry entry : _statUse.entrySet()) + { + final StatusUpdateType stat = entry.getKey(); + final double requiredAmount = entry.getValue(); + + switch (stat) + { + case CUR_HP: + { + manufacturer.reduceCurrentHp(requiredAmount, manufacturer, null); + break; + } + case CUR_MP: + { + manufacturer.reduceCurrentMp(requiredAmount); + break; + } + case CUR_CP: + { + manufacturer.getStatus().reduceCp((int) requiredAmount); + break; + } + case EXP: + { + manufacturer.getStat().removeExp((long) requiredAmount); + break; + } + case REPUTATION: + { + manufacturer.setReputation((int) (manufacturer.getReputation() - requiredAmount)); + break; + } + } + } + + // Take necessary ingredients. If there was problem destroying item, return null to insicate that process didn't go well. + if (getMaterials().stream().anyMatch(i -> !player.destroyItemByItemId("Recipe " + getId(), i.getId(), i.getCount(), manufacturer, sendMessage))) + { + return null; + } + + // Check if success. Luck triggers no matter the success rate - even with 100% craft. Luck chance is taken from your stat and not manufacturer's stat. + final ItemHolder result = getRandomProduct(); + if (success) + { + player.addItem("Craft", result, manufacturer, true); + + // Award another item if its crafting critical. Double blessed items is very, very rare, but still possible. + if (craftingCritical) + { + player.addItem("CraftCritical", result, manufacturer, true); + } + } + + return result; + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/itemcontainer/Inventory.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/itemcontainer/Inventory.java index 88575164db..c5f33c86df 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/itemcontainer/Inventory.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/itemcontainer/Inventory.java @@ -401,7 +401,7 @@ public abstract class Inventory extends ItemContainer final L2PcInstance player = (L2PcInstance) inventory.getOwner(); // Any items equipped that result in expertise penalty do not give any skills at all. - if (item.getItem().getCrystalType().getId() > player.getExpertiseLevel()) + if (item.getItem().getCrystalType().isGreater(player.getExpertiseLevel())) { return; } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/L2Item.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/L2Item.java index 2f590854f8..0f672fa66d 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/L2Item.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/L2Item.java @@ -134,7 +134,7 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable private int _time; private int _autoDestroyTime; private int _bodyPart; - private int _referencePrice; + private long _referencePrice; private int _crystalCount; private boolean _sellable; private boolean _dropable; @@ -200,7 +200,7 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable _time = set.getInt("time", -1); _autoDestroyTime = set.getInt("auto_destroy_time", -1) * 1000; _bodyPart = ItemTable.SLOTS.get(set.getString("bodypart", "none")); - _referencePrice = set.getInt("price", 0); + _referencePrice = set.getLong("price", 0); _crystalType = set.getEnum("crystal_type", CrystalType.class, CrystalType.NONE); _crystalCount = set.getInt("crystal_count", 0); @@ -538,7 +538,7 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable /** * @return the price of reference of the item. */ - public final int getReferencePrice() + public final long getReferencePrice() { return _referencePrice; } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/instance/L2ItemInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/instance/L2ItemInstance.java index ebd3c44be4..fb63011022 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/instance/L2ItemInstance.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/instance/L2ItemInstance.java @@ -731,7 +731,7 @@ public final class L2ItemInstance extends L2Object /** * @return the reference price of the item. */ - public int getReferencePrice() + public long getReferencePrice() { return _item.getReferencePrice(); } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/type/CrystalType.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/type/CrystalType.java index 6f0351fc9e..f87f2ec4a0 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/type/CrystalType.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/items/type/CrystalType.java @@ -35,14 +35,14 @@ public enum CrystalType R99(10, 17371, 30, 500), EVENT(11, 0, 0, 0); - private final int _id; + private final int _level; private final int _crystalId; private final int _crystalEnchantBonusArmor; private final int _crystalEnchantBonusWeapon; - CrystalType(int id, int crystalId, int crystalEnchantBonusArmor, int crystalEnchantBonusWeapon) + CrystalType(int level, int crystalId, int crystalEnchantBonusArmor, int crystalEnchantBonusWeapon) { - _id = id; + _level = level; _crystalId = crystalId; _crystalEnchantBonusArmor = crystalEnchantBonusArmor; _crystalEnchantBonusWeapon = crystalEnchantBonusWeapon; @@ -52,9 +52,9 @@ public enum CrystalType * Gets the crystal type ID. * @return the crystal type ID */ - public int getId() + public int getLevel() { - return _id; + return _level; } /** @@ -78,11 +78,41 @@ public enum CrystalType public boolean isGreater(CrystalType crystalType) { - return getId() > crystalType.getId(); + return getLevel() > crystalType.getLevel(); } public boolean isLesser(CrystalType crystalType) { - return getId() < crystalType.getId(); + return getLevel() < crystalType.getLevel(); + } + + public CrystalType plusLevel(int level) + { + level += getLevel(); + + if (level >= CrystalType.R99.getLevel()) + { + return CrystalType.R99; + } + + if (level <= CrystalType.NONE.getLevel()) + { + return CrystalType.NONE; + } + + return getByLevel(level); + } + + public static CrystalType getByLevel(int level) + { + for (CrystalType crystalType : values()) + { + if (crystalType.getLevel() == level) + { + return crystalType; + } + } + + return null; } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java index 3eb0a2828c..5d43bf448a 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -266,6 +266,7 @@ public enum Stats // Which base stat ordinal should alter skill critical formula. STAT_BONUS_SKILL_CRITICAL("statSkillCritical"), STAT_BONUS_SPEED("statSpeed"), + CRAFTING_CRITICAL("craftingCritical"), SHOTS_BONUS("shotBonus", new ShotsBonusFinalizer()); static final Logger LOGGER = Logger.getLogger(Stats.class.getName()); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/L2GameClient.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/L2GameClient.java index f0fc7726d3..629b0afc09 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/L2GameClient.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/L2GameClient.java @@ -790,7 +790,7 @@ public final class L2GameClient extends ChannelInboundHandler } default: { - canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isInCraftMode(); + canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isCrafting(); break; } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookDestroy.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookDestroy.java index c84bf256a2..bed25678de 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookDestroy.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookDestroy.java @@ -18,9 +18,11 @@ package com.l2jmobius.gameserver.network.clientpackets; import com.l2jmobius.commons.network.PacketReader; import com.l2jmobius.gameserver.data.xml.impl.RecipeData; -import com.l2jmobius.gameserver.model.L2RecipeList; +import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList; public final class RequestRecipeBookDestroy implements IClientIncomingPacket @@ -48,23 +50,24 @@ public final class RequestRecipeBookDestroy implements IClientIncomingPacket return; } - final L2RecipeList rp = RecipeData.getInstance().getRecipeList(_recipeID); - if (rp == null) + if ((activeChar.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) || activeChar.isCrafting()) { + activeChar.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING); return; } + + final RecipeHolder rp = RecipeData.getInstance().getRecipe(_recipeID); + if (rp == null) + { + client.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT); + return; + } + + // Remove the recipe from the list. activeChar.unregisterRecipeList(_recipeID); - final RecipeBookItemList response = new RecipeBookItemList(rp.isDwarvenRecipe(), activeChar.getMaxMp()); - if (rp.isDwarvenRecipe()) - { - response.addRecipes(activeChar.getDwarvenRecipeBook()); - } - else - { - response.addRecipes(activeChar.getCommonRecipeBook()); - } - + // Send the new recipe book. + final RecipeBookItemList response = new RecipeBookItemList(activeChar, rp.isDwarvenRecipe()); activeChar.sendPacket(response); } } \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookOpen.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookOpen.java index 26a453d3ff..01a8faf4f7 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookOpen.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeBookOpen.java @@ -17,10 +17,11 @@ package com.l2jmobius.gameserver.network.clientpackets; import com.l2jmobius.commons.network.PacketReader; -import com.l2jmobius.gameserver.RecipeController; +import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.network.L2GameClient; import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.RecipeBookItemList; public final class RequestRecipeBookOpen implements IClientIncomingPacket { @@ -48,12 +49,19 @@ public final class RequestRecipeBookOpen implements IClientIncomingPacket return; } - if (activeChar.getActiveRequester() != null) + if (activeChar.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) { - activeChar.sendMessage("You may not alter your recipe book while trading."); + client.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING); return; } - RecipeController.getInstance().requestBookOpen(activeChar, _isDwarvenCraft); + if (activeChar.isProcessingTransaction()) + { + client.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE); + return; + } + + final RecipeBookItemList response = new RecipeBookItemList(activeChar, _isDwarvenCraft); + activeChar.sendPacket(response); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeInfo.java index 64f44c07f2..e393db0631 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeInfo.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeInfo.java @@ -17,8 +17,11 @@ package com.l2jmobius.gameserver.network.clientpackets; import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.data.xml.impl.RecipeData; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.RecipeItemMakeInfo; public final class RequestRecipeItemMakeInfo implements IClientIncomingPacket @@ -41,6 +44,13 @@ public final class RequestRecipeItemMakeInfo implements IClientIncomingPacket return; } - client.sendPacket(new RecipeItemMakeInfo(_id, player)); + final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_id); + if (recipe == null) + { + player.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT); + return; + } + + client.sendPacket(new RecipeItemMakeInfo(_id, player, recipe.getMaxOffering())); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeSelf.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeSelf.java index 8aa642c02a..a2415834ec 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeSelf.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeItemMakeSelf.java @@ -16,23 +16,45 @@ */ package com.l2jmobius.gameserver.network.clientpackets; +import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketReader; -import com.l2jmobius.gameserver.RecipeController; +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.data.xml.impl.RecipeData; import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; +import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; +import com.l2jmobius.gameserver.model.stats.Stats; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.RecipeItemMakeInfo; +import com.l2jmobius.gameserver.util.Util; /** - * @author Administrator + * @author Nik */ public final class RequestRecipeItemMakeSelf implements IClientIncomingPacket { private int _id; + private ItemHolder[] _offeredItems; @Override public boolean read(L2GameClient client, PacketReader packet) { _id = packet.readD(); + + final int offeringsCount = packet.readD(); + if (offeringsCount > 0) + { + _offeredItems = new ItemHolder[offeringsCount]; + for (int i = 0; i < offeringsCount; i++) + { + final int objectId = packet.readD(); + final long count = packet.readQ(); + _offeredItems[i] = new ItemHolder(objectId, count); + } + } return true; } @@ -45,23 +67,122 @@ public final class RequestRecipeItemMakeSelf implements IClientIncomingPacket return; } + if (!Config.IS_CRAFTING_ENABLED) + { + activeChar.sendMessage("Item creation is currently disabled."); + return; + } + if (!client.getFloodProtectors().getManufacture().tryPerformAction("RecipeMakeSelf")) { return; } - if (activeChar.getPrivateStoreType() != PrivateStoreType.NONE) + if (activeChar.isCastingNow()) { - activeChar.sendMessage("You cannot create items while trading."); + activeChar.sendPacket(SystemMessageId.YOUR_RECIPE_BOOK_MAY_NOT_BE_ACCESSED_WHILE_USING_A_SKILL); return; } - if (activeChar.isInCraftMode()) + if (activeChar.getPrivateStoreType() == PrivateStoreType.MANUFACTURE) { - activeChar.sendMessage("You are currently in Craft Mode."); + activeChar.sendPacket(SystemMessageId.YOU_MAY_NOT_ALTER_YOUR_RECIPE_BOOK_WHILE_ENGAGED_IN_MANUFACTURING); return; } - RecipeController.getInstance().requestMakeItem(activeChar, _id); + if (activeChar.isProcessingTransaction()) + { + activeChar.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE); + return; + } + + // TODO: Check if its a retail-like check. + if (activeChar.isAlikeDead()) + { + return; + } + + // On retail if player is requesting trade, it is instantly canceled. + activeChar.cancelActiveTrade(); + + final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_id); + if (recipe == null) + { + activeChar.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT); + return; + } + + if (!activeChar.hasRecipeList(recipe.getId())) + { + Util.handleIllegalPlayerAction(activeChar, "Warning!! Character " + activeChar.getName() + " of account " + activeChar.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH); + return; + } + + // Check if stats or ingredients are met. + if (!recipe.checkNecessaryStats(activeChar, activeChar, true) || !recipe.checkNecessaryIngredients(activeChar, true)) + { + return; + } + + // Check if all offerings are legit. + if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0)) + { + for (ItemHolder offer : _offeredItems) + { + final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId()); + if ((item == null) || (item.getCount() < offer.getCount()) || !item.isDestroyable()) + { + return; + } + } + } + + if (activeChar.isCrafting()) + { + activeChar.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT); + return; + } + + activeChar.setIsCrafting(true); + + // Take offerings to increase chance + double offeringBonus = 0; + if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0)) + { + long offeredAdenaWorth = 0; + for (ItemHolder offer : _offeredItems) + { + final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId()); + if (activeChar.destroyItem("CraftOffering", item, offer.getCount(), null, true)) + { + offeredAdenaWorth += (item.getItem().getReferencePrice() * offer.getCount()); + } + } + + offeringBonus = Math.min((offeredAdenaWorth / recipe.getMaxOffering()) * recipe.getMaxOfferingBonus(), recipe.getMaxOfferingBonus()); + } + + final boolean success = activeChar.tryLuck() || ((recipe.getSuccessRate() + offeringBonus) > Rnd.get(100)); + final boolean craftingCritical = success && (activeChar.getStat().getValue(Stats.CRAFTING_CRITICAL) > Rnd.get(100)); + + if (success) // Successful craft. + { + if (craftingCritical) + { + activeChar.sendPacket(SystemMessageId.CRAFTING_CRITICAL); + } + } + else // Failed craft. + { + activeChar.sendPacket(SystemMessageId.YOU_FAILED_AT_MIXING_THE_ITEM); + } + + // Perform the crafting: take the items and give reward if success. + recipe.doCraft(activeChar, activeChar, success, craftingCritical, true); + + // Send craft window. Must be sent after crafting so it properly counts the items. + activeChar.sendPacket(new RecipeItemMakeInfo(recipe.getId(), activeChar, success, recipe.getMaxOffering())); + + activeChar.setIsCrafting(false); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopListSet.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopListSet.java index 2c7aaa9a84..d4385ae32c 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopListSet.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopListSet.java @@ -18,16 +18,17 @@ package com.l2jmobius.gameserver.network.clientpackets; import static com.l2jmobius.gameserver.model.itemcontainer.Inventory.MAX_ADENA; -import java.util.Arrays; -import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketReader; import com.l2jmobius.gameserver.data.xml.impl.RecipeData; +import com.l2jmobius.gameserver.datatables.ItemTable; import com.l2jmobius.gameserver.enums.PrivateStoreType; -import com.l2jmobius.gameserver.model.L2ManufactureItem; -import com.l2jmobius.gameserver.model.L2RecipeList; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.model.zone.ZoneId; import com.l2jmobius.gameserver.network.L2GameClient; import com.l2jmobius.gameserver.network.SystemMessageId; @@ -44,28 +45,28 @@ public final class RequestRecipeShopListSet implements IClientIncomingPacket { private static final int BATCH_LENGTH = 12; - private L2ManufactureItem[] _items = null; + private Map _manufactureRecipes = null; @Override public boolean read(L2GameClient client, PacketReader packet) { - final int count = packet.readD(); + int count = packet.readD(); if ((count <= 0) || (count > Config.MAX_ITEM_IN_PACKET) || ((count * BATCH_LENGTH) != packet.getReadableBytes())) { return false; } - _items = new L2ManufactureItem[count]; + _manufactureRecipes = new HashMap<>(count); for (int i = 0; i < count; i++) { - final int id = packet.readD(); - final long cost = packet.readQ(); + int id = packet.readD(); + long cost = packet.readQ(); if (cost < 0) { - _items = null; + _manufactureRecipes = null; return false; } - _items[i] = new L2ManufactureItem(id, cost); + _manufactureRecipes.put(id, cost); } return true; } @@ -79,13 +80,26 @@ public final class RequestRecipeShopListSet implements IClientIncomingPacket return; } - if (_items == null) + if (_manufactureRecipes == null) { + player.sendPacket(SystemMessageId.ITEMS_ARE_NOT_AVAILABLE_FOR_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP); player.setPrivateStoreType(PrivateStoreType.NONE); player.broadcastUserInfo(); return; } + if (player.isCastingNow()) + { + player.sendPacket(SystemMessageId.A_PRIVATE_STORE_MAY_NOT_BE_OPENED_WHILE_USING_A_SKILL); + return; + } + + if (player.isCrafting()) + { + player.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT); + return; + } + if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player) || player.isInDuel()) { client.sendPacket(SystemMessageId.WHILE_YOU_ARE_ENGAGED_IN_COMBAT_YOU_CANNOT_OPERATE_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP); @@ -100,29 +114,36 @@ public final class RequestRecipeShopListSet implements IClientIncomingPacket return; } - final List dwarfRecipes = Arrays.asList(player.getDwarvenRecipeBook()); - final List commonRecipes = Arrays.asList(player.getCommonRecipeBook()); - - player.getManufactureItems().clear(); - - for (L2ManufactureItem i : _items) + for (Entry item : _manufactureRecipes.entrySet()) { - final L2RecipeList list = RecipeData.getInstance().getRecipeList(i.getRecipeId()); - if (!dwarfRecipes.contains(list) && !commonRecipes.contains(list)) + final int recipeId = item.getKey(); + final long recipeCost = item.getValue(); + final RecipeHolder recipe = RecipeData.getInstance().getRecipe(recipeId); + if (recipe == null) + { + player.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT); + return; + } + if (ItemTable.getInstance().getTemplate(recipe.getItemId()).isQuestItem()) + { + player.sendPacket(SystemMessageId.QUEST_RECIPES_CAN_NOT_BE_REGISTERED); + return; + } + if (!player.hasRecipeList(recipe.getId())) { Util.handleIllegalPlayerAction(player, "Warning!! Player " + player.getName() + " of account " + player.getAccountName() + " tried to set recipe which he dont have.", Config.DEFAULT_PUNISH); return; } - if (i.getCost() > MAX_ADENA) + if (recipeCost > MAX_ADENA) { - Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " tried to set price more than " + MAX_ADENA + " adena in Private Manufacture.", Config.DEFAULT_PUNISH); + Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " tried to set price of " + recipeCost + " adena in Private Manufacture.", Config.DEFAULT_PUNISH); return; } - - player.getManufactureItems().put(i.getRecipeId(), i); } + player.setManufactureItems(_manufactureRecipes); + player.setStoreName(!player.hasManufactureShop() ? "" : player.getStoreName()); player.setPrivateStoreType(PrivateStoreType.MANUFACTURE); player.sitDown(); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeInfo.java index 12f915819f..4e6a68fdc4 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeInfo.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeInfo.java @@ -17,10 +17,13 @@ package com.l2jmobius.gameserver.network.clientpackets; import com.l2jmobius.commons.network.PacketReader; +import com.l2jmobius.gameserver.data.xml.impl.RecipeData; import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.RecipeShopItemInfo; /** @@ -49,12 +52,25 @@ public final class RequestRecipeShopMakeInfo implements IClientIncomingPacket return; } - final L2PcInstance shop = L2World.getInstance().getPlayer(_playerObjectId); - if ((shop == null) || (shop.getPrivateStoreType() != PrivateStoreType.MANUFACTURE)) + final L2PcInstance manufacturer = L2World.getInstance().getPlayer(_playerObjectId); + if ((manufacturer == null) || (manufacturer.getPrivateStoreType() != PrivateStoreType.MANUFACTURE)) { return; } - client.sendPacket(new RecipeShopItemInfo(shop, _recipeId)); + final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_recipeId); + if (recipe == null) + { + player.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT); + return; + } + + final Long manufactureRecipeCost = manufacturer.getManufactureItems().get(_recipeId); + if (manufactureRecipeCost == null) + { + return; + } + + client.sendPacket(new RecipeShopItemInfo(manufacturer, _recipeId, manufactureRecipeCost, recipe.getMaxOffering())); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeItem.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeItem.java index ba40366a3e..38401cb4ae 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeItem.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopMakeItem.java @@ -16,30 +16,53 @@ */ package com.l2jmobius.gameserver.network.clientpackets; +import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketReader; -import com.l2jmobius.gameserver.RecipeController; +import com.l2jmobius.commons.util.Rnd; +import com.l2jmobius.gameserver.data.xml.impl.RecipeData; import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.ItemHolder; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; +import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; +import com.l2jmobius.gameserver.model.stats.Stats; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.RecipeShopItemInfo; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; import com.l2jmobius.gameserver.util.Util; /** - * @author Administrator + * It appears you are able to successfully create from manufacture store while casting, while in manufacture store and within 250 range. So basic checks
+ * from your own recipe list crafting are skipped. With the exception of trading, if you request trade, it is cancelled, if you are already trading, you get message. + * @author Nik */ public final class RequestRecipeShopMakeItem implements IClientIncomingPacket { - private int _id; + private int _objectId; private int _recipeId; - @SuppressWarnings("unused") - private long _unknown; + private long _manufacturePrice; + private ItemHolder[] _offeredItems; @Override public boolean read(L2GameClient client, PacketReader packet) { - _id = packet.readD(); + _objectId = packet.readD(); _recipeId = packet.readD(); - _unknown = packet.readQ(); + _manufacturePrice = packet.readQ(); + + final int offeringsCount = packet.readD(); + if (offeringsCount > 0) + { + _offeredItems = new ItemHolder[offeringsCount]; + for (int i = 0; i < offeringsCount; i++) + { + final int objectId = packet.readD(); + final long count = packet.readQ(); + _offeredItems[i] = new ItemHolder(objectId, count); + } + } return true; } @@ -52,41 +75,197 @@ public final class RequestRecipeShopMakeItem implements IClientIncomingPacket return; } + if (!Config.IS_CRAFTING_ENABLED) + { + activeChar.sendMessage("Item creation is currently disabled."); + return; + } + if (!client.getFloodProtectors().getManufacture().tryPerformAction("RecipeShopMake")) { return; } - final L2PcInstance manufacturer = L2World.getInstance().getPlayer(_id); + final L2PcInstance manufacturer = L2World.getInstance().getPlayer(_objectId); if (manufacturer == null) { return; } - if (manufacturer.getInstanceWorld() != activeChar.getInstanceWorld()) + if ((manufacturer.getInstanceWorld() != activeChar.getInstanceWorld()) || (activeChar.calculateDistance(manufacturer, false, false) > 250)) { return; } - if (activeChar.getPrivateStoreType() != PrivateStoreType.NONE) - { - activeChar.sendMessage("You cannot create items while trading."); - return; - } if (manufacturer.getPrivateStoreType() != PrivateStoreType.MANUFACTURE) { - // activeChar.sendMessage("You cannot create items while trading."); return; } - if (activeChar.isInCraftMode() || manufacturer.isInCraftMode()) + if (activeChar.isProcessingTransaction() || manufacturer.isProcessingTransaction()) { - activeChar.sendMessage("You are currently in Craft Mode."); + activeChar.sendPacket(SystemMessageId.ITEM_CREATION_IS_NOT_POSSIBLE_WHILE_ENGAGED_IN_A_TRADE); return; } - if (Util.checkIfInRange(150, activeChar, manufacturer, true)) + + // TODO: Check if its a retail-like check. + if (activeChar.isAlikeDead() || manufacturer.isAlikeDead()) { - RecipeController.getInstance().requestManufactureItem(manufacturer, _recipeId, activeChar); + return; } + + // On retail if player is requesting trade, it is instantly canceled. + activeChar.cancelActiveTrade(); + + final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_recipeId); + if (recipe == null) + { + activeChar.sendPacket(SystemMessageId.THE_RECIPE_IS_INCORRECT); + return; + } + + if (!manufacturer.hasRecipeList(recipe.getId())) + { + Util.handleIllegalPlayerAction(activeChar, "Warning!! Character " + activeChar.getName() + " of account " + activeChar.getAccountName() + " sent a false recipe id.", Config.DEFAULT_PUNISH); + return; + } + + final Long manufactureRecipeCost = manufacturer.getManufactureItems().get(_recipeId); + if (manufactureRecipeCost == null) + { + return; + } + + // Check if the price is the same as requested price. + if (_manufacturePrice != manufactureRecipeCost) + { + return; + } + + // Check if player can pay. + if (activeChar.getAdena() < manufactureRecipeCost) + { + activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA); + return; + } + + // Check if stats or ingredients are met. + if (!recipe.checkNecessaryStats(activeChar, manufacturer, true) || !recipe.checkNecessaryIngredients(activeChar, true)) + { + return; + } + + // Check if all offerings are legit. + if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0)) + { + for (ItemHolder offer : _offeredItems) + { + final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId()); + if ((item == null) || (item.getCount() < offer.getCount()) || !item.isDestroyable()) + { + return; + } + } + } + + if (manufacturer.isCrafting()) + { + activeChar.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT); + return; + } + + manufacturer.setIsCrafting(true); + + // First you must pay for the manufacturing service of the other player. + if (manufactureRecipeCost > 0) + { + // Attempt to pay the required manufacturing price by the manufacturer. + L2ItemInstance paidAdena = activeChar.transferItem("PayManufacture", activeChar.getInventory().getAdenaInstance().getObjectId(), manufactureRecipeCost, manufacturer.getInventory(), manufacturer); + + if (paidAdena == null) + { + activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA); + return; + } + } + + // Take offerings to increase chance + double offeringBonus = 0; + if ((_offeredItems != null) && (recipe.getMaxOffering() > 0) && (recipe.getMaxOfferingBonus() > 0)) + { + long offeredAdenaWorth = 0; + for (ItemHolder offer : _offeredItems) + { + final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(offer.getId()); + if (activeChar.destroyItem("CraftOffering", item, offer.getCount(), manufacturer, true)) + { + offeredAdenaWorth += (item.getItem().getReferencePrice() * offer.getCount()); + } + } + + offeringBonus = Math.min((offeredAdenaWorth / recipe.getMaxOffering()) * recipe.getMaxOfferingBonus(), recipe.getMaxOfferingBonus()); + } + + final boolean success = activeChar.tryLuck() || ((recipe.getSuccessRate() + offeringBonus) > Rnd.get(100)); + final boolean craftingCritical = success && (activeChar.getStat().getValue(Stats.CRAFTING_CRITICAL) > Rnd.get(100)); + + final ItemHolder craftedItem = recipe.doCraft(activeChar, manufacturer, success, craftingCritical, true); + if (success) + { + if (craftingCritical) + { + activeChar.sendPacket(SystemMessageId.CRAFTING_CRITICAL); + } + if (craftedItem.getCount() > 1) + { + SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S3_S2_S_HAVE_BEEN_CREATED_FOR_C1_AT_THE_PRICE_OF_S4_ADENA); + sm.addString(activeChar.getName()); + sm.addInt((int) craftedItem.getCount()); + sm.addItemName(craftedItem.getId()); + sm.addLong(manufactureRecipeCost); + manufacturer.sendPacket(sm); + + sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S3_S2_S_AT_THE_PRICE_OF_S4_ADENA); + sm.addString(manufacturer.getName()); + sm.addInt((int) craftedItem.getCount()); + sm.addItemName(craftedItem.getId()); + sm.addLong(manufactureRecipeCost); + activeChar.sendPacket(sm); + } + else + { + + SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HAS_BEEN_CREATED_FOR_C1_AFTER_THE_PAYMENT_OF_S3_ADENA_WAS_RECEIVED); + sm.addString(activeChar.getName()); + sm.addItemName(craftedItem.getId()); + sm.addLong(manufactureRecipeCost); + manufacturer.sendPacket(sm); + + sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CREATED_S2_AFTER_RECEIVING_S3_ADENA); + sm.addString(manufacturer.getName()); + sm.addItemName(craftedItem.getId()); + sm.addLong(manufactureRecipeCost); + activeChar.sendPacket(sm); + } + } + else + { + SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_FAILED_TO_CREATE_S2_FOR_C1_AT_THE_PRICE_OF_S3_ADENA); + sm.addString(activeChar.getName()); + sm.addItemName(craftedItem.getId()); + sm.addLong(manufactureRecipeCost); + manufacturer.sendPacket(sm); + + sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_FAILED_TO_CREATE_S2_AT_THE_PRICE_OF_S3_ADENA); + sm.addString(manufacturer.getName()); + sm.addItemName(craftedItem.getId()); + sm.addLong(manufactureRecipeCost); + activeChar.sendPacket(sm); + } + + // Show manufacturing window. + activeChar.sendPacket(new RecipeShopItemInfo(manufacturer, recipe.getId(), success, _manufacturePrice, recipe.getMaxOffering())); + + manufacturer.setIsCrafting(false); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManageList.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManageList.java index 59b5957d8e..15ac35b4bf 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManageList.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManageList.java @@ -19,9 +19,12 @@ package com.l2jmobius.gameserver.network.clientpackets; import com.l2jmobius.commons.network.PacketReader; import com.l2jmobius.gameserver.enums.PrivateStoreType; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.zone.ZoneId; import com.l2jmobius.gameserver.network.L2GameClient; +import com.l2jmobius.gameserver.network.SystemMessageId; import com.l2jmobius.gameserver.network.serverpackets.ActionFailed; import com.l2jmobius.gameserver.network.serverpackets.RecipeShopManageList; +import com.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager; public final class RequestRecipeShopManageList implements IClientIncomingPacket { @@ -40,6 +43,38 @@ public final class RequestRecipeShopManageList implements IClientIncomingPacket return; } + if (player.getCommonRecipeBook().isEmpty() && player.getDwarvenRecipeBook().isEmpty()) + { + player.sendPacket(SystemMessageId.NO_RECIPES_HAVE_BEEN_REGISTERED); + return; + } + + if (player.isCastingNow()) + { + player.sendPacket(SystemMessageId.A_PRIVATE_STORE_MAY_NOT_BE_OPENED_WHILE_USING_A_SKILL); + return; + } + + if (player.isCrafting()) + { + player.sendPacket(SystemMessageId.CURRENTLY_CRAFTING_AN_ITEM_PLEASE_WAIT); + return; + } + + if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player) || player.isInDuel()) + { + client.sendPacket(SystemMessageId.WHILE_YOU_ARE_ENGAGED_IN_COMBAT_YOU_CANNOT_OPERATE_A_PRIVATE_STORE_OR_PRIVATE_WORKSHOP); + client.sendPacket(ActionFailed.STATIC_PACKET); + return; + } + + if (player.isInsideZone(ZoneId.NO_STORE)) + { + client.sendPacket(SystemMessageId.YOU_CANNOT_OPEN_A_PRIVATE_WORKSHOP_HERE); + client.sendPacket(ActionFailed.STATIC_PACKET); + return; + } + // Player shouldn't be able to set stores if he/she is alike dead (dead or fake death) if (player.isAlikeDead()) { diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManagePrev.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManagePrev.java index 8b59287b33..52fb7e31b4 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManagePrev.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/RequestRecipeShopManagePrev.java @@ -42,7 +42,14 @@ public final class RequestRecipeShopManagePrev implements IClientIncomingPacket { return; } - else if (player.isAlikeDead() || (player.getTarget() == null) || !player.getTarget().isPlayer()) + + if (player.isAlikeDead() || (player.getTarget() == null) || !player.getTarget().isPlayer()) + { + client.sendPacket(ActionFailed.STATIC_PACKET); + return; + } + + if (player.calculateDistance(player.getTarget(), false, false) > 250) { client.sendPacket(ActionFailed.STATIC_PACKET); return; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/alchemy/RequestAlchemyTryMixCube.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/alchemy/RequestAlchemyTryMixCube.java index dad7c7aefa..86324a84a0 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/alchemy/RequestAlchemyTryMixCube.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/alchemy/RequestAlchemyTryMixCube.java @@ -120,7 +120,7 @@ public class RequestAlchemyTryMixCube implements IClientIncomingPacket return; } - final int price = itemInstance.getReferencePrice(); + final long price = itemInstance.getReferencePrice(); if (itemInstance.getReferencePrice() == 0) { player.sendPacket(SystemMessageId.THIS_ITEM_CANNOT_BE_COMBINED); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingEnchantSupportItem.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingEnchantSupportItem.java index b3f8a823c8..ad3f971eda 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingEnchantSupportItem.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingEnchantSupportItem.java @@ -59,7 +59,7 @@ public class RequestExTryToPutShapeShiftingEnchantSupportItem implements IClient final ShapeShiftingItemRequest request = player.getRequest(ShapeShiftingItemRequest.class); - if (player.isInStoreMode() || player.isInCraftMode() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null)) + if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null)) { client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP); return; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingTargetItem.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingTargetItem.java index 4fe4ef7d8c..75c44c649d 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingTargetItem.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestExTryToPutShapeShiftingTargetItem.java @@ -54,7 +54,7 @@ public class RequestExTryToPutShapeShiftingTargetItem implements IClientIncoming final ShapeShiftingItemRequest request = player.getRequest(ShapeShiftingItemRequest.class); - if (player.isInStoreMode() || player.isInCraftMode() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null)) + if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null)) { client.sendPacket(ExPutShapeShiftingTargetItemResult.FAILED); client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestShapeShiftingItem.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestShapeShiftingItem.java index 97d035b0f3..1d6ef78348 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestShapeShiftingItem.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/appearance/RequestShapeShiftingItem.java @@ -62,7 +62,7 @@ public class RequestShapeShiftingItem implements IClientIncomingPacket final ShapeShiftingItemRequest request = player.getRequest(ShapeShiftingItemRequest.class); - if (player.isInStoreMode() || player.isInCraftMode() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null)) + if (player.isInStoreMode() || player.isCrafting() || player.isProcessingRequest() || player.isProcessingTransaction() || (request == null)) { client.sendPacket(ExShapeShiftingResult.CLOSE); client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THIS_SYSTEM_DURING_TRADING_PRIVATE_STORE_AND_WORKSHOP_SETUP); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowCropSetting.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowCropSetting.java index 8be8b98259..b5dd119973 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowCropSetting.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowCropSetting.java @@ -77,7 +77,7 @@ public class ExShowCropSetting implements IClientOutgoingPacket packet.writeD(s.getCropLimit()); // next sale limit packet.writeD(0); // ??? packet.writeD(s.getCropMinPrice()); // min crop price - packet.writeD(s.getCropMaxPrice()); // max crop price + packet.writeD((int) s.getCropMaxPrice()); // max crop price // Current period if (_current.containsKey(s.getCropId())) { diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowManorDefaultInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowManorDefaultInfo.java index 8516330479..52f23f1fca 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowManorDefaultInfo.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowManorDefaultInfo.java @@ -48,8 +48,8 @@ public final class ExShowManorDefaultInfo implements IClientOutgoingPacket { packet.writeD(crop.getCropId()); // crop Id packet.writeD(crop.getLevel()); // level - packet.writeD(crop.getSeedReferencePrice()); // seed price - packet.writeD(crop.getCropReferencePrice()); // crop price + packet.writeD((int) crop.getSeedReferencePrice()); // seed price + packet.writeD((int) crop.getCropReferencePrice()); // crop price packet.writeC(1); // Reward 1 type packet.writeD(crop.getReward(1)); // Reward 1 itemId packet.writeC(1); // Reward 2 type diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowSeedSetting.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowSeedSetting.java index 40c0360538..5f76c46f65 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowSeedSetting.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ExShowSeedSetting.java @@ -75,9 +75,9 @@ public class ExShowSeedSetting implements IClientOutgoingPacket packet.writeC(1); packet.writeD(s.getReward(2)); // reward 2 id packet.writeD(s.getSeedLimit()); // next sale limit - packet.writeD(s.getSeedReferencePrice()); // price for castle to produce 1 - packet.writeD(s.getSeedMinPrice()); // min seed price - packet.writeD(s.getSeedMaxPrice()); // max seed price + packet.writeD((int) s.getSeedReferencePrice()); // price for castle to produce 1 + packet.writeD((int) s.getSeedMinPrice()); // min seed price + packet.writeD((int) s.getSeedMaxPrice()); // max seed price // Current period if (_current.containsKey(s.getSeedId())) { diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/GMViewCharacterInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/GMViewCharacterInfo.java index d67302fa42..f376dc11dc 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/GMViewCharacterInfo.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/GMViewCharacterInfo.java @@ -137,7 +137,7 @@ public class GMViewCharacterInfo implements IClientOutgoingPacket packet.writeD(_activeChar.getAllyId()); // ally id packet.writeC(_activeChar.getMountType().ordinal()); // mount type packet.writeC(_activeChar.getPrivateStoreType().getId()); - packet.writeC(_activeChar.hasDwarvenCraft() ? 1 : 0); + packet.writeC(_activeChar.getCreateItemLevel() > 0 ? 1 : 0); packet.writeD(_activeChar.getPkKills()); packet.writeD(_activeChar.getPvpKills()); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeBookItemList.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeBookItemList.java index e972857e29..5c0dc5c556 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeBookItemList.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeBookItemList.java @@ -16,25 +16,24 @@ */ package com.l2jmobius.gameserver.network.serverpackets; +import java.util.Collection; + import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.L2RecipeList; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.network.OutgoingPackets; public class RecipeBookItemList implements IClientOutgoingPacket { - private L2RecipeList[] _recipes; + private final Collection _recipes; private final boolean _isDwarvenCraft; private final int _maxMp; - public RecipeBookItemList(boolean isDwarvenCraft, int maxMp) + public RecipeBookItemList(L2PcInstance player, boolean isDwarvenCraft) { _isDwarvenCraft = isDwarvenCraft; - _maxMp = maxMp; - } - - public void addRecipes(L2RecipeList[] recipeBook) - { - _recipes = recipeBook; + _maxMp = player.getMaxMp(); + _recipes = (isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook()); } @Override @@ -51,11 +50,12 @@ public class RecipeBookItemList implements IClientOutgoingPacket } else { - packet.writeD(_recipes.length); // number of items in recipe book - for (int i = 0; i < _recipes.length; i++) + packet.writeD(_recipes.size()); // number of items in recipe book + int i = 1; + for (RecipeHolder recipe : _recipes) { - packet.writeD(_recipes[i].getId()); - packet.writeD(i + 1); + packet.writeD(recipe.getId()); + packet.writeD(i++); } } return true; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeItemMakeInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeItemMakeInfo.java index 6397e049ac..9a47f0c939 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeItemMakeInfo.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeItemMakeInfo.java @@ -18,34 +18,53 @@ package com.l2jmobius.gameserver.network.serverpackets; import com.l2jmobius.commons.network.PacketWriter; import com.l2jmobius.gameserver.data.xml.impl.RecipeData; -import com.l2jmobius.gameserver.model.L2RecipeList; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.network.OutgoingPackets; public class RecipeItemMakeInfo implements IClientOutgoingPacket { private final int _id; private final L2PcInstance _activeChar; - private final boolean _success; + private final Boolean _success; + private final long _offeringMaximumAdena; + + public RecipeItemMakeInfo(int id, L2PcInstance player, boolean success, long offeringMaximumAdena) + { + _id = id; + _activeChar = player; + _success = success; + _offeringMaximumAdena = offeringMaximumAdena; + } public RecipeItemMakeInfo(int id, L2PcInstance player, boolean success) { _id = id; _activeChar = player; _success = success; + _offeringMaximumAdena = 0; + } + + public RecipeItemMakeInfo(int id, L2PcInstance player, long offeringMaximumAdena) + { + _id = id; + _activeChar = player; + _success = null; + _offeringMaximumAdena = offeringMaximumAdena; } public RecipeItemMakeInfo(int id, L2PcInstance player) { _id = id; _activeChar = player; - _success = true; + _success = null; + _offeringMaximumAdena = 0; } @Override public boolean write(PacketWriter packet) { - final L2RecipeList recipe = RecipeData.getInstance().getRecipeList(_id); + final RecipeHolder recipe = RecipeData.getInstance().getRecipe(_id); if (recipe != null) { OutgoingPackets.RECIPE_ITEM_MAKE_INFO.writeId(packet); @@ -53,9 +72,9 @@ public class RecipeItemMakeInfo implements IClientOutgoingPacket packet.writeD(recipe.isDwarvenRecipe() ? 0 : 1); // 0 = Dwarven - 1 = Common packet.writeD((int) _activeChar.getCurrentMp()); packet.writeD(_activeChar.getMaxMp()); - packet.writeD(_success ? 1 : 0); // item creation success/failed - packet.writeC(0x00); - packet.writeQ(0x00); + packet.writeD(_success == null ? -1 : (_success ? 1 : 0)); // item creation none/success/failed + packet.writeC(_offeringMaximumAdena > 0 ? 1 : 0); // Show offering window. + packet.writeQ(_offeringMaximumAdena); // Adena worth of items for maximum offering. return true; } _log.info("Character: " + _activeChar + ": Requested unexisting recipe with id = " + _id); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopItemInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopItemInfo.java index 95090c8f30..086f3d6103 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopItemInfo.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopItemInfo.java @@ -22,13 +22,28 @@ import com.l2jmobius.gameserver.network.OutgoingPackets; public class RecipeShopItemInfo implements IClientOutgoingPacket { - private final L2PcInstance _player; + private final L2PcInstance _manufacturer; private final int _recipeId; + private final Boolean _success; + private final long _manufacturePrice; + private final long _offeringMaximumAdena; - public RecipeShopItemInfo(L2PcInstance player, int recipeId) + public RecipeShopItemInfo(L2PcInstance manufacturer, int recipeId, boolean success, long manufacturePrice, long offeringMaximumAdena) { - _player = player; + _manufacturer = manufacturer; _recipeId = recipeId; + _success = success; + _manufacturePrice = manufacturePrice; + _offeringMaximumAdena = offeringMaximumAdena; + } + + public RecipeShopItemInfo(L2PcInstance manufacturer, int recipeId, long manufacturePrice, long offeringMaximumAdena) + { + _manufacturer = manufacturer; + _recipeId = recipeId; + _success = null; + _manufacturePrice = manufacturePrice; + _offeringMaximumAdena = offeringMaximumAdena; } @Override @@ -36,14 +51,14 @@ public class RecipeShopItemInfo implements IClientOutgoingPacket { OutgoingPackets.RECIPE_SHOP_ITEM_INFO.writeId(packet); - packet.writeD(_player.getObjectId()); + packet.writeD(_manufacturer.getObjectId()); packet.writeD(_recipeId); - packet.writeD((int) _player.getCurrentMp()); - packet.writeD(_player.getMaxMp()); - packet.writeD(0xffffffff); - packet.writeQ(0x00); - packet.writeC(0x00); // Trigger offering window if 1 - packet.writeQ(0x00); + packet.writeD((int) _manufacturer.getCurrentMp()); + packet.writeD(_manufacturer.getMaxMp()); + packet.writeD(_success == null ? -1 : (_success ? 1 : 0)); // item creation none/success/failed + packet.writeQ(_manufacturePrice); + packet.writeC(_offeringMaximumAdena > 0 ? 1 : 0); // Trigger offering window if 1 + packet.writeQ(_offeringMaximumAdena); return true; } } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopManageList.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopManageList.java index 3aa7b5c70c..318e490a91 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopManageList.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopManageList.java @@ -16,44 +16,39 @@ */ package com.l2jmobius.gameserver.network.serverpackets; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map.Entry; import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.L2ManufactureItem; -import com.l2jmobius.gameserver.model.L2RecipeList; +import com.l2jmobius.gameserver.data.xml.impl.RecipeData; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.holders.RecipeHolder; import com.l2jmobius.gameserver.network.OutgoingPackets; public class RecipeShopManageList implements IClientOutgoingPacket { private final L2PcInstance _seller; private final boolean _isDwarven; - private L2RecipeList[] _recipes; + private final Collection _recipes; + private List> _manufacture; public RecipeShopManageList(L2PcInstance seller, boolean isDwarven) { _seller = seller; _isDwarven = isDwarven; - - if (_isDwarven && _seller.hasDwarvenCraft()) - { - _recipes = _seller.getDwarvenRecipeBook(); - } - else - { - _recipes = _seller.getCommonRecipeBook(); - } + _recipes = (isDwarven && (_seller.getCreateItemLevel() > 0)) ? _seller.getDwarvenRecipeBook() : _seller.getCommonRecipeBook(); if (_seller.hasManufactureShop()) { - final Iterator it = _seller.getManufactureItems().values().iterator(); - L2ManufactureItem item; - while (it.hasNext()) + _manufacture = new ArrayList<>(); + for (Entry item : _seller.getManufactureItems().entrySet()) { - item = it.next(); - if ((item.isDwarven() != _isDwarven) || !seller.hasRecipeList(item.getRecipeId())) + final RecipeHolder recipe = RecipeData.getInstance().getRecipe(item.getKey()); + if (((recipe != null) && (recipe.isDwarvenRecipe() == _isDwarven)) && seller.hasRecipeList(recipe.getId())) { - it.remove(); + _manufacture.add(item); } } } @@ -68,34 +63,34 @@ public class RecipeShopManageList implements IClientOutgoingPacket packet.writeD((int) _seller.getAdena()); packet.writeD(_isDwarven ? 0x00 : 0x01); - if (_recipes == null) + if ((_recipes == null) || _recipes.isEmpty()) { packet.writeD(0); } else { - packet.writeD(_recipes.length); // number of items in recipe book + packet.writeD(_recipes.size());// number of items in recipe book - for (int i = 0; i < _recipes.length; i++) + int i = 1; + for (RecipeHolder recipe : _recipes) { - final L2RecipeList temp = _recipes[i]; - packet.writeD(temp.getId()); - packet.writeD(i + 1); + packet.writeD(recipe.getId()); + packet.writeD(i++); } } - if (!_seller.hasManufactureShop()) + if ((_manufacture == null) || _manufacture.isEmpty()) { packet.writeD(0x00); } else { - packet.writeD(_seller.getManufactureItems().size()); - for (L2ManufactureItem item : _seller.getManufactureItems().values()) + packet.writeD(_manufacture.size()); + for (Entry item : _manufacture) { - packet.writeD(item.getRecipeId()); - packet.writeD(0x00); - packet.writeQ(item.getCost()); + packet.writeD(item.getKey()); + packet.writeD(0x00); // CanCraft? + packet.writeQ(item.getValue()); } } return true; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopSellList.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopSellList.java index 8a6638e153..5788685406 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopSellList.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/RecipeShopSellList.java @@ -16,8 +16,9 @@ */ package com.l2jmobius.gameserver.network.serverpackets; +import java.util.Map.Entry; + import com.l2jmobius.commons.network.PacketWriter; -import com.l2jmobius.gameserver.model.L2ManufactureItem; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; @@ -47,11 +48,11 @@ public class RecipeShopSellList implements IClientOutgoingPacket else { packet.writeD(_manufacturer.getManufactureItems().size()); - for (L2ManufactureItem temp : _manufacturer.getManufactureItems().values()) + for (Entry item : _manufacturer.getManufactureItems().entrySet()) { - packet.writeD(temp.getRecipeId()); - packet.writeD(0x00); // unknown - packet.writeQ(temp.getCost()); + packet.writeD(item.getKey()); + packet.writeD(0x00); // CanCreate? + packet.writeQ(item.getValue()); } } return true; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/SellList.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/SellList.java index 433eae9095..e10221838e 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/SellList.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/SellList.java @@ -76,7 +76,7 @@ public class SellList implements IClientOutgoingPacket for (L2ItemInstance item : _sellList) { - int price = item.getItem().getReferencePrice() / 2; + long price = item.getItem().getReferencePrice() / 2; if (_merchant != null) { price -= (price * _merchant.getTotalTaxRate(TaxType.SELL)); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ShopPreviewList.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ShopPreviewList.java index 438e259df2..7ecb2ebd18 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ShopPreviewList.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/ShopPreviewList.java @@ -23,6 +23,7 @@ import com.l2jmobius.commons.network.PacketWriter; import com.l2jmobius.gameserver.model.buylist.L2BuyList; import com.l2jmobius.gameserver.model.buylist.Product; import com.l2jmobius.gameserver.model.items.L2Item; +import com.l2jmobius.gameserver.model.items.type.CrystalType; import com.l2jmobius.gameserver.network.OutgoingPackets; public class ShopPreviewList implements IClientOutgoingPacket @@ -30,14 +31,14 @@ public class ShopPreviewList implements IClientOutgoingPacket private final int _listId; private final Collection _list; private final long _money; - private int _expertise; + private CrystalType _expertise; - public ShopPreviewList(L2BuyList list, long currentMoney, int expertiseIndex) + public ShopPreviewList(L2BuyList list, long currentMoney, CrystalType expertise) { _listId = list.getListId(); _list = list.getProducts(); _money = currentMoney; - _expertise = expertiseIndex; + _expertise = expertise; } public ShopPreviewList(Collection lst, int listId, long currentMoney) @@ -59,7 +60,7 @@ public class ShopPreviewList implements IClientOutgoingPacket int newlength = 0; for (Product product : _list) { - if ((product.getItem().getCrystalType().getId() <= _expertise) && product.getItem().isEquipable()) + if (!product.getItem().getCrystalType().isGreater(_expertise) && product.getItem().isEquipable()) { newlength++; } @@ -68,7 +69,7 @@ public class ShopPreviewList implements IClientOutgoingPacket for (Product product : _list) { - if ((product.getItem().getCrystalType().getId() <= _expertise) && product.getItem().isEquipable()) + if (!product.getItem().getCrystalType().isGreater(_expertise) && product.getItem().isEquipable()) { packet.writeD(product.getItemId()); packet.writeH(product.getItem().getType2()); // item type2 diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/UserInfo.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/UserInfo.java index 3972277e4c..b9cca5a15e 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/UserInfo.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/serverpackets/UserInfo.java @@ -20,6 +20,7 @@ import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketWriter; import com.l2jmobius.gameserver.data.xml.impl.ExperienceData; import com.l2jmobius.gameserver.enums.AttributeType; +import com.l2jmobius.gameserver.enums.ItemGrade; import com.l2jmobius.gameserver.enums.UserInfoType; import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager; import com.l2jmobius.gameserver.model.L2Clan; @@ -205,7 +206,7 @@ public class UserInfo extends AbstractMaskPacket packet.writeH(6); packet.writeC(_activeChar.getMountType().ordinal()); packet.writeC(_activeChar.getPrivateStoreType().getId()); - packet.writeC(_activeChar.hasDwarvenCraft() || (_activeChar.getSkillLevel(248) > 0) ? 1 : 0); + packet.writeC(_activeChar.getCrystallizeGrade() != ItemGrade.NONE ? 1 : 0); packet.writeC(_activeChar.getAbilityPoints() - _activeChar.getAbilityPointsUsed()); }