diff --git a/CraftingRecipes/craftbot.json b/CraftingRecipes/craftbot.json new file mode 100644 index 0000000..ea91864 --- /dev/null +++ b/CraftingRecipes/craftbot.json @@ -0,0 +1,2494 @@ +[ + { + // "Diamond Plate Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 20 + } + ], + "itemId": "c97c17c3-81bb-48b5-9e9c-8a5117ee431a", + "quantity": 10 + }, + { + // "Paintable Glass Flat Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 20 + } + ], + "itemId": "036ffd32-45df-11e6-beb8-9e71128cae77", + "quantity": 10 + }, + { + // "Glowing Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 5 + }, + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 5 + } + ], + "itemId": "e50485da-4545-4def-a585-0a5f158c6104", + "quantity": 10 + }, + { + // "Invisible Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 30 + } + ], + "itemId": "7a73cc98-b2d4-4b28-9095-f8b9077548e4", + "quantity": 10 + }, + { + // "Mirror Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "b5ee5539-75a2-4fef-873b-ef7c9398b3f5", + "quantity": 10 + } + ], + "itemId": "906c76ee-189a-4983-ae82-b31722e56b23", + "quantity": 10 + }, + { + // "Bling Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 100 + } + ], + "itemId": "bc3efcdf-ae18-4037-b0aa-c5af14e03547", + "quantity": 10 + }, + { + // "Game Grid Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 30 + } + ], + "itemId": "b51ad015-66e9-41b9-916c-277f9c93232d", + "quantity": 10 + }, + { + // "Luxury Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 100 + } + ], + "itemId": "e7f7b758-6492-4c6a-8760-8fb95da530be", + "quantity": 1 + }, + { + // "Smooth Ice", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "30a2288b-e88e-4a92-a916-1edbfc2b2dac", + "quantity": 4 + }, + { + "itemId": "869d4736-289a-4952-96cd-8a40117a2d28", + "quantity": 5 + } + ], + "itemId": "116325e1-1020-40ec-8f31-0678f8bb98bc", + "quantity": 10 + }, + { + // "Icy Rocks", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "30a2288b-e88e-4a92-a916-1edbfc2b2dac", + "quantity": 4 + }, + { + "itemId": "869d4736-289a-4952-96cd-8a40117a2d28", + "quantity": 5 + } + ], + "itemId": "b742cff1-98a7-469f-b514-a7402f705924", + "quantity": 10 + }, + { + // "Rubber Block", + "craftTime": 15, + "ingredientList": [ + { + "itemId": "30a2288b-e88e-4a92-a916-1edbfc2b2dac", + "quantity": 4 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "123425e2-2020-40ec-8f31-0678f8bc99bd", + "quantity": 10 + }, + { + // "Reduced Collision Block", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + } + ], + "itemId": "bf8f8e24-806b-4223-9345-2bac7c1e265d", + "quantity": 1 + }, + { + // "Vent Block", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + } + ], + "itemId": "9c40e3ab-8d03-40bc-a88b-eaebc61257d6", + "quantity": 1 + }, + { + // "Invisible Bearing", + "craftTime": 30, + "ingredientList": [ + { + "itemId": "1f7ac0bb-ad45-4246-9817-59bdf7f7ab39", + "quantity": 20 + } + ], + "itemId": "ebafd24a-7bbc-4e75-87f5-a67cdcf31e29", + "quantity": 1 + }, + { + // "Steering Pipe", + "craftTime": 30, + "ingredientList": [ + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 20 + } + ], + "itemId": "8f762ab9-5c78-4d9c-a22e-3119bf447169", + "quantity": 1 + }, + { + // "Mini Suspension - Short", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 4 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 2 + } + ], + "itemId": "c0d086eb-de4a-4ba9-922a-1c66f129d2ae", + "quantity": 1 + }, + { + // "Mini Suspension - Long", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "8d6e5264-9f90-400a-a471-6c0cae101f4d", + "quantity": 1 + }, + { + // "Suspension - 4x", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 7 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "9f016a8d-8cbe-4471-b210-f36f5f280758", + "quantity": 1 + }, + { + // "Suspension - 5x", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 10 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + } + ], + "itemId": "dd676b18-fd06-4aed-baa0-55d4599fdfa3", + "quantity": 1 + }, + { + // "Engine Suspension", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 15 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 15 + } + ], + "itemId": "b69bf080-2467-4360-9677-72cfd48806c9", + "quantity": 1 + }, + { + // "Mod Piston (256)", + "craftTime": 0, + "ingredientList": [ + { + "itemId": "1016cafc-9f6b-40c9-8713-9019d399783f", + "quantity": 10 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 2 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 15 + } + ], + "itemId": "a6d186ad-c9ba-4b6d-922c-6c13dfcea230", + "quantity": 1 + }, + { + // "Motorcycle Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 4 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "0513fc6d-fb29-46b6-9409-3ec1a4b79c6f", + "quantity": 1 + }, + { + // "Racing Driver Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 4 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "ffddc616-2799-4883-8c62-193ba30b6fa8", + "quantity": 1 + }, + { + // "Racing Passenger Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "8c355d48-88cd-467b-863f-12c12b72304d", + "quantity": 1 + }, + { + // "Ship's Wheel Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 10 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "88e045aa-d3ab-435e-b248-60b34c206e6f", + "quantity": 1 + }, + { + // "Jetpack Seat - Or Mech, Gunner, etc", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "ad671132-c345-4edc-96c7-ec835ab3a2c9", + "quantity": 1 + }, + { + // "Standing Driver Seat", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "3b41f562-70c4-4747-9045-3d26ff0e0243", + "quantity": 1 + }, + { + // "Sleeping Bed - Driver", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 20 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "a3da3841-5a76-4d72-a177-cdc4e572efc7", + "quantity": 1 + }, + { + // "Driver's Pillow", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "784bf71e-2331-4d56-a70f-b00a3994231b", + "quantity": 1 + }, + { + // "Modular Seat 1 - Standard", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 7 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "b15f557c-872f-4bf5-9c0b-2891a34f430e", + "quantity": 1 + }, + { + // "Modular Seat 2 - Saddle", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 7 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 7 + } + ], + "itemId": "86d5ca1b-f1fa-42a9-9645-0d276e711b27", + "quantity": 1 + }, + { + // "Modular Seat 3 - Race", + "craftTime": 57, + "ingredientList": [ + { + "itemId": "3440440b-d362-4473-aa03-b7c41e1fe7ad", + "quantity": 5 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "d9f49f49-0ef9-41d6-a9a5-ec454be87082", + "quantity": 1 + }, + { + // "Arrow Button", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "685ccdd5-8ee9-480d-a64a-2696c31e1db0", + "quantity": 1 + }, + { + // "Hidden Button Block", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "e426ee20-2cf7-40c9-ad5e-145f43752fab", + "quantity": 1 + }, + { + // "Pull-start Button", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "f694b406-4f59-46cb-bf33-05e11851eaac", + "quantity": 1 + }, + { + // "Dial Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "deeb37a4-b9ba-4ba7-ad4b-6f5fd5e1d6f2", + "quantity": 1 + }, + { + // "Paddle Latch Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "70e5729d-0706-4c28-80a2-2ab9d7e7532c", + "quantity": 1 + }, + { + // "Door Handle Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "f6619b4a-a627-40c0-939c-a44432ebc66a", + "quantity": 1 + }, + { + // "Throttle Lever - Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "7022c522-7b33-4638-8dfb-0dfa7c6eb36f", + "quantity": 1 + }, + { + // "Medium Lever - Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "e9ab70ae-2c6c-4f68-86c3-2f652c180fc5", + "quantity": 1 + }, + { + // "Large Lever - Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "ee92187e-8363-4ff6-a7ae-c96e60450537", + "quantity": 1 + }, + { + // "Pipe Valve Switch", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + } + ], + "itemId": "73f35954-e7d2-4a32-bc7c-b88a341ab792", + "quantity": 1 + }, + { + // "Pixel Light Block - Black-Off, Light-On", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "7947150d-a21c-4195-a4a8-76aab023ba3c", + "quantity": 1 + }, + { + // "Off/On Light - Round", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "bfbd310d-7c07-4f08-a8cc-9a69e70a9ff0", + "quantity": 1 + }, + { + // "Off/On Light - Rectangle", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "d7de689e-5082-4323-b6c4-eb1ce8f29719", + "quantity": 1 + }, + { + // "Off/On Light - Round Mini", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "5a3ea22a-99b1-48eb-b169-3243ad49b27c", + "quantity": 1 + }, + { + // "Off/On Light - Square", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "7b51eae8-c55c-4102-b9eb-6c23ca547e83", + "quantity": 1 + }, + { + // "Off/On Light - Cube", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "e83e6fd9-e963-485f-8be0-43895af58ee3", + "quantity": 1 + }, + { + // "Slim Light", + "craftTime": 2, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 1 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 1 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "0f994efc-b697-48e4-8ce0-f53eae15d41b", + "quantity": 1 + }, + { + // "Surface Controller", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "9687439e-70a7-4c52-8dd1-d6fa6ec93df8", + "quantity": 1 + }, + { + // "Surface Logic", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "60375a3b-0d70-43a2-a97a-4a4234b500dd", + "quantity": 1 + }, + { + // "Surface Timer", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "f6b70b49-ea25-47cc-9dac-e2dc90e67d07", + "quantity": 1 + }, + { + // "Decoupler", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + } + ], + "itemId": "f907144d-ae63-4e5e-bff9-f9ca413e2090", + "quantity": 1 + }, + { + // "Time Block ", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "6613bebe-be9f-435c-b415-42a0b45cc8e3", + "quantity": 1 + }, + { + // "Smart Sensor", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "5f41af56-df4c-4837-9b3c-10781335757f", + "quantity": 4 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 6 + } + ], + "itemId": "4081ca6f-6b80-4c39-9e79-e1f747039bec", + "quantity": 1 + }, + { + // "Laser Sight", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "c7a99aa6-c5a4-43ad-84c9-c85f7d842a93", + "quantity": 1 + }, + { + // "Tracker", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 10 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 25 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 30 + } + ], + "itemId": "6594dff0-c652-4b44-8bb6-c725aaadea05", + "quantity": 1 + }, + { + // "Radar Jammer", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 30 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 20 + } + ], + "itemId": "55bb3871-8455-40dc-a968-3dc635a32b7e", + "quantity": 1 + }, + { + // "Wireless Router", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 13 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 20 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 20 + } + ], + "itemId": "e627986c-b7dd-4365-8fd8-a0f8707af63d", + "quantity": 1 + }, + { + // "Orientation Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "ccaa33b6-e5bb-4edc-9329-b40f6efe2c9e", + "quantity": 1 + }, + { + // "Number Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "efbd14a8-f896-4268-a273-b2b382db520c", + "quantity": 1 + }, + { + // "Math Block\n(Function Block)", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "289e08ef-e3d8-4f1b-bc10-a0bcf36fa0ce", + "quantity": 1 + }, + { + // "Counter", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "d8296109-2ffb-4efb-819a-54bd8cadf549", + "quantity": 1 + }, + { + // "Memory Panel", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "b39faec9-1ed0-4475-8bc0-78d125df1b58", + "quantity": 1 + }, + { + // "x-o-meter", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "d88ba569-f7a5-42e3-bb11-d7979b60ddad", + "quantity": 1 + }, + { + // "Tick Button", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 2 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 2 + } + ], + "itemId": "6f2dd83e-bc0d-43f3-8ba5-d5209eb03d07", + "quantity": 1 + }, + { + // "Smart Timer", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "a1d0b1a0-4ec7-4614-8b7a-9a7c521cc03e", + "quantity": 1 + }, + { + // "Keypad Input", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "d3eda549-778f-432b-bf21-65a32ae53378", + "quantity": 1 + }, + { + // "Color Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "921a2ace-b543-4ca3-8a9b-6f3dd3132fa9", + "quantity": 1 + }, + { + // "Ascii Block", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "9c47ec58-bdfc-43a4-b066-852156ad812a", + "quantity": 1 + }, + { + // "Ascii Block Inverted", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "8d27520e-2ebc-4f14-bd2c-b99ee8976799", + "quantity": 1 + }, + { + // "Ascii Block Colored", + "craftTime": 87, + "ingredientList": [ + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 10 + } + ], + "itemId": "a459eb96-7f0a-42e6-a841-44f9c0561a55", + "quantity": 1 + }, + { + // "Smart Engine Controller", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 40 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 20 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 20 + } + ], + "itemId": "fe8978ec-5798-4b24-bdb2-8375387f171b", + "quantity": 1 + }, + { + // "Gas Engine 3-Wide", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "c0dfdea5-a39d-433a-b94a-299345a5df46", + "quantity": 20 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "70cbacf2-ec5a-471f-9896-0ee944c581d1", + "quantity": 1 + }, + { + // "Pico thruster - Low power", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "c0dfdea5-a39d-433a-b94a-299345a5df46", + "quantity": 20 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "9235b582-fc25-48a8-a807-68d98755d077", + "quantity": 1 + }, + { + // "1x1 Micro Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "c0dfdea5-a39d-433a-b94a-299345a5df46", + "quantity": 20 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 5 + } + ], + "itemId": "a07a3673-a446-44a3-b16d-abb732c7a525", + "quantity": 1 + }, + { + // "Smart Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 35 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 17 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 30 + } + ], + "itemId": "a4342028-9a61-4961-99a4-2ae372ee2481", + "quantity": 1 + }, + { + // "WASD Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 35 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 15 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 25 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 25 + } + ], + "itemId": "cec7c353-34ab-43a4-ade5-411df02eaa2a", + "quantity": 1 + }, + { + // "Gimbal Thruster", + "craftTime": 60, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "1147e59d-6940-42b4-840b-07f05054f5e0", + "quantity": 25 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 15 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 25 + } + ], + "itemId": "41d596a6-882c-4f97-b0e0-3e11bff194e2", + "quantity": 1 + }, + { + // "Gravity Module", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 45 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 30 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 55 + } + ], + "itemId": "c9e34f58-b30d-4ab5-92c5-76f707090c45", + "quantity": 1 + }, + { + // "Gravity Modulator", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 50 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 40 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 60 + } + ], + "itemId": "e93ca226-4166-49e3-97cd-bb8df20242d7", + "quantity": 1 + }, + { + // "Large Wing", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "e2cc7014-85f3-4bb8-a7ca-b70b6502d91e", + "quantity": 1 + }, + { + // "Small Wing / Propeller", + "craftTime": 20, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "1bfccc0a-828f-475c-882c-87d5a96054c9", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 1 + } + ], + "itemId": "b5222776-1702-4c22-a8c5-ca26cc0290e7", + "quantity": 1 + }, + { + // "Timed Explosive - Dynamite", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 10 + } + ], + "itemId": "c071509a-9854-4359-8857-296f16edf15d", + "quantity": 1 + }, + { + // "Tone Generator", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 3 + } + ], + "itemId": "f73fd8c7-61eb-416f-8374-9a4c26e6db8f", + "quantity": 1 + }, + { + // "Smart Totebot", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 5 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 1 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 4 + } + ], + "itemId": "1d5d997e-efa9-478c-98ee-e452f5ff0dd2", + "quantity": 1 + }, + { + // "Radar", + "craftTime": 37, + "ingredientList": [ + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 10 + }, + { + "itemId": "f152e4df-bc40-44fb-8d20-3b3ff70cdfe3", + "quantity": 5 + }, + { + "itemId": "5530e6a0-4748-4926-b134-50ca9ecb9dcf", + "quantity": 3 + }, + { + "itemId": "36335664-6e61-4d44-9876-54f9660a8565", + "quantity": 10 + } + ], + "itemId": "a053e38d-608b-4b9a-8d04-c3da2b6fdff7", + "quantity": 1 + }, + { + // "Roller Wheel - 1x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 3 + } + ], + "itemId": "b57c8185-2f95-4ba8-818d-eed258e01d00", + "quantity": 1 + }, + { + // "Roller Wheel - 2x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 6 + } + ], + "itemId": "4e1452d0-a9c2-42d4-91cf-1aea84c533ed", + "quantity": 1 + }, + { + // "Rounded Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "c460f40f-c7b7-4695-a627-9f01749724b6", + "quantity": 1 + }, + { + // "Hubless Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "c9cf3b88-86f3-4146-af16-a7b16c917ecc", + "quantity": 1 + }, + { + // "Invisible Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "4358b01f-3303-42a2-91d2-cc950e23b59b", + "quantity": 1 + }, + { + // "Dirt Wheel - 3x1/2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 13 + } + ], + "itemId": "27b6541d-2be0-420f-abb8-d59f566e85bd", + "quantity": 1 + }, + { + // "Dirt Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "68a7fe0a-4d48-4552-a29d-044d3c7b9e02", + "quantity": 1 + }, + { + // "Dirt Wheel - 4x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 16 + } + ], + "itemId": "92d3c375-0e45-4df4-8691-90e49e8ce24d", + "quantity": 1 + }, + { + // "Dirt Wheel - 5x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 18 + } + ], + "itemId": "041ae0ae-07d5-4ac5-9767-be396ba2445d", + "quantity": 1 + }, + { + // "Dirt Wheel - 5x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "c47ff0cd-e1f2-4727-ba40-c85d0512d6d0", + "quantity": 1 + }, + { + // "Dirt Wheel - 5x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 20 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 21 + } + ], + "itemId": "784bf162-b2d1-4a6d-9cf4-091827871a40", + "quantity": 1 + }, + { + // "Street Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "5a9ff028-a6cb-4010-bcd4-c88eb230bcdb", + "quantity": 1 + }, + { + // "Street Wheel - 4x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 17 + } + ], + "itemId": "58e7fdd0-9f15-466c-aaba-60805044fe67", + "quantity": 1 + }, + { + // "Street Wheel - 4x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 18 + } + ], + "itemId": "3147a872-cb90-487c-b6ce-438c6403b09c", + "quantity": 1 + }, + { + // "Street Wheel - 5x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "a02f96b2-26c3-4b3e-a00c-32254af91a5d", + "quantity": 1 + }, + { + // "Street Wheel - 6x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 22 + } + ], + "itemId": "d3954d83-78ee-4fbf-9a60-70e4872e1d39", + "quantity": 1 + }, + { + // "Combat Wheel - 3x1", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 25 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 15 + } + ], + "itemId": "d59bd448-6401-4476-849a-e6fc86d28b7b", + "quantity": 1 + }, + { + // "Combat Wheel - 5x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "96fc86b1-57e7-4795-9d39-90e74f52ba87", + "quantity": 1 + }, + { + // "Combat Wheel - 7x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 28 + } + ], + "itemId": "fafdc38f-e374-49fd-8fea-4062a4b5c93a", + "quantity": 1 + }, + { + // "Combat Wheel - 9x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "4dee7b84-ee4c-42ce-9a42-4c6ced837ff5", + "quantity": 1 + }, + { + // "Combat Wheel - 11x4", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 32 + } + ], + "itemId": "583f20c9-a7da-477b-b852-aac404467e3a", + "quantity": 1 + }, + { + // "Combat Wheel - 13x5", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 30 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 35 + } + ], + "itemId": "90bc9601-b874-45e2-8970-09d5e5ff3ca9", + "quantity": 1 + }, + { + // "Sand Wheel - 3x2", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 20 + } + ], + "itemId": "abe5a33f-a3cc-41a8-b32a-731ec2b184c1", + "quantity": 1 + }, + { + // "Sand Wheel - 5x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 25 + } + ], + "itemId": "0761c82c-7a3f-4c22-8ec1-46223f10a2de", + "quantity": 1 + }, + { + // "Sand Wheel - 7x4", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "ee8869cb-9cce-43c3-a04a-e8b37b9de0ed", + "quantity": 1 + }, + { + // "Sand Wheel - 9x5", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 35 + } + ], + "itemId": "2210586c-3a93-43ff-b861-542e2d2d12d6", + "quantity": 1 + }, + { + // "Sand Wheel - 11x6", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 40 + } + ], + "itemId": "6afcb463-925a-4a2e-b9bf-3397ef094df9", + "quantity": 1 + }, + { + // "Sand Wheel - 13x6", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 45 + } + ], + "itemId": "b0f71aed-04f0-4bba-b969-cba57f3fc667", + "quantity": 1 + }, + { + // "Sand Wheel - 15x7", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 50 + } + ], + "itemId": "87f8f460-eba5-43c1-a1ad-facfb3d3f376", + "quantity": 1 + }, + { + // "Sand Wheel - 17x8", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 55 + } + ], + "itemId": "2bcc8c8f-1e94-4f9d-97b9-6e7423ca40b0", + "quantity": 1 + }, + { + // "Sand Wheel - 19x9", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 15 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 60 + } + ], + "itemId": "61a70b37-ea24-4022-b1e6-45a5a3ae179d", + "quantity": 1 + }, + { + // "Big Wheel - 7x3", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 40 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 30 + } + ], + "itemId": "036fc6d2-45df-11e6-beb8-9e71128cae77", + "quantity": 1 + }, + { + // "Big Wheel - 9x4", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 40 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 35 + } + ], + "itemId": "036fc79a-45df-11e6-beb8-9e71128cae77", + "quantity": 1 + }, + { + // "Chained Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 50 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 50 + } + ], + "itemId": "d739fdf9-2c61-47ea-88ab-beac6a6c35c0", + "quantity": 1 + }, + { + // "Spiked Wheel", + "craftTime": 27, + "ingredientList": [ + { + "itemId": "df953d9c-234f-4ac2-af5e-f0490b223e71", + "quantity": 15 + }, + { + "itemId": "8aedf6c2-94e1-4506-89d4-a0227c552f1e", + "quantity": 60 + }, + { + "itemId": "fcf0958c-084d-4854-9b1b-b06594b4262a", + "quantity": 60 + } + ], + "itemId": "d739fdf9-2c61-47ea-88ab-beac6a6c35c1", + "quantity": 1 + } +] \ No newline at end of file diff --git a/Gui/IconMap.xml b/Gui/IconMap.xml index e49f441..4f10f83 100644 --- a/Gui/IconMap.xml +++ b/Gui/IconMap.xml @@ -59,6 +59,9 @@ + + + @@ -97,13 +100,22 @@ + + + + + + + + + diff --git a/Gui/Language/Chinese/inventoryDescriptions.json b/Gui/Language/Chinese/inventoryDescriptions.json index c813fd1..ef87daf 100644 --- a/Gui/Language/Chinese/inventoryDescriptions.json +++ b/Gui/Language/Chinese/inventoryDescriptions.json @@ -92,6 +92,10 @@ "description": "适用于长行程悬挂" }, "93e08947-be6d-436c-a64f-932727428c89": { + "title": "悬架发动机 [#ffff00已弃用#ffffff]", + "description": "可以放在轴承上作为悬挂的零件,\n并且作为燃气发动机使用." + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "悬架发动机", "description": "可以放在轴承上作为悬挂的零件,\n并且作为燃气发动机使用." }, @@ -154,16 +158,31 @@ }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "燃气发动机-宽 [#ffff00已弃用#ffffff]", + "description": "完美平衡的奇数!" + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "燃气发动机-宽", "description": "完美平衡的奇数!" }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "迷你喷射器-低功率 [#ffff00已弃用#ffffff]", + "description": "适用于微调的喷射器" + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "迷你喷射器-低功率", "description": "适用于微调的喷射器" }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 迷你喷射器 [#ffff00已弃用#ffffff]", + "description": "推力稍大的迷你喷射器" + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 迷你喷射器", "description": "推力稍大的迷你喷射器" diff --git a/Gui/Language/Dutch/inventoryDescriptions.json b/Gui/Language/Dutch/inventoryDescriptions.json index a85c0f0..0159271 100644 --- a/Gui/Language/Dutch/inventoryDescriptions.json +++ b/Gui/Language/Dutch/inventoryDescriptions.json @@ -148,11 +148,21 @@ "description": "Een onzichtbaar bestuurders zetel dat kan geplaats worden op andere blokken" }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Motor Vering [#ffff00VEROUDERD#ffffff]", + "description": "Dit deel is een motor! Zet dit deel op een lager en connecteer deze motor met de lager! Zet de kracht van de motor voor de kracht van de vering" + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Motor Vering", "description": "Dit deel is een motor! Zet dit deel op een lager en connecteer deze motor met de lager! Zet de kracht van de motor voor de kracht van de vering" }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "3 wijde motor [#ffff00VEROUDERD#ffffff]", + "description": "Het is een benzine motor die 3 wijd is. Perfect voor gelijke wagens te maken" + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "3 wijde motor", "description": "Het is een benzine motor die 3 wijd is. Perfect voor gelijke wagens te maken" @@ -160,6 +170,11 @@ "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico Stuwer - Lage kracht [#ffff00VEROUDERD#ffffff]", + "description": "Bestuurs Stuwer, of gewoon een lage kracht stuwer" + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico Stuwer - Lage kracht", "description": "Bestuurs Stuwer, of gewoon een lage kracht stuwer" @@ -555,6 +570,11 @@ "description": "A controller with a different appearance" }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Mini stuwer [#ffff00VEROUDERD#ffffff]", + "description": "Mini stuwer met meerdere kracht-levels" + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Mini stuwer", "description": "Mini stuwer met meerdere kracht-levels" diff --git a/Gui/Language/English/inventoryDescriptions.json b/Gui/Language/English/inventoryDescriptions.json index 54a0fb2..015786f 100644 --- a/Gui/Language/English/inventoryDescriptions.json +++ b/Gui/Language/English/inventoryDescriptions.json @@ -112,6 +112,12 @@ "keywords": [ "modpack", "spring" ] }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Engine Suspension [#ffff00DEPRECATED#ffffff]", + "description": "This part is an engine! Put this part on a bearing and connect this engine to the bearing! Connect some pipes to one end where your wheel (and steering) will go, and use the other end to limit the range of movement. Set the power of this engine for a loose or firm engine-suspension.", + "keywords": [ "modpack", "motor", "suspension", "spring", "angle", "controller" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Engine Suspension", "description": "This part is an engine! Put this part on a bearing and connect this engine to the bearing! Connect some pipes to one end where your wheel (and steering) will go, and use the other end to limit the range of movement. Set the power of this engine for a loose or firm engine-suspension.", @@ -194,18 +200,36 @@ // engines "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Gas Engine 3-Wide [#ffff00DEPRECATED#ffffff]", + "description": "It's a gas engine that conforms to the size of an electric engine. Perfect for balance gas-powered odd-width creations!", + "keywords": [ "modpack", "motor", "odd", "odd-width", "width" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Gas Engine 3-Wide", "description": "It's a gas engine that conforms to the size of an electric engine. Perfect for balance gas-powered odd-width creations!", "keywords": [ "modpack", "motor", "odd", "odd-width", "width" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico thruster - Low power [#ffff00DEPRECATED#ffffff]", + "description": "Maneuvering thrusters, or just a low power thruster", + "keywords": [ "modpack", "rocket", "booster", "boost", "force", "exhaust" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico thruster - Low power", "description": "Maneuvering thrusters, or just a low power thruster", "keywords": [ "modpack", "rocket", "booster", "boost", "force", "exhaust" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro Thruster [#ffff00DEPRECATED#ffffff]", + "description": "Micro Thruster with more power levels", + "keywords": [ "modpack", "rocket", "booster", "boost", "force", "exhaust" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro Thruster", "description": "Micro Thruster with more power levels", diff --git a/Gui/Language/French/inventoryDescriptions.json b/Gui/Language/French/inventoryDescriptions.json index 03473e1..6ce313a 100644 --- a/Gui/Language/French/inventoryDescriptions.json +++ b/Gui/Language/French/inventoryDescriptions.json @@ -99,6 +99,12 @@ "description": "Cette pi�ce est un moteur! Placez cette pi�ce sur un roulement et connectez ce moteur au roulement! Connectez des tuyaux � une extr�mit� o� iront votre roue (et votre direction) et utilisez l'autre extr�mit� pour limiter la port�e R�gler la puissance de ce moteur pour une suspension de moteur l�che ou ferme. ", "keywords": ["modpack", "moteur", "suspension", "ressort", "angle", "contr�leur"] }, + "b69bf080-2467-4360-9677-72cfd48806c9": + { + "title": "Suspension de moteur [#ffff00OBSOLÈTE#ffffff]", + "description": "Cette pi�ce est un moteur! Placez cette pi�ce sur un roulement et connectez ce moteur au roulement! Connectez des tuyaux � une extr�mit� o� iront votre roue (et votre direction) et utilisez l'autre extr�mit� pour limiter la port�e R�gler la puissance de ce moteur pour une suspension de moteur l�che ou ferme. ", + "keywords": ["modpack", "moteur", "suspension", "ressort", "angle", "contr�leur"] + }, "a6d186ad-c9ba-4b6d-922c-6c13dfcea230": { "title": "Mod Piston (256)", @@ -176,18 +182,36 @@ // moteurs "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Gas Engine 3-Wide [#ffff00OBSOLÈTE#ffffff]", + "description": "Il s�agit d�un moteur � essence de la taille d�un moteur �lectrique. Id�al pour les cr�ations � largeur irr�guli�re � essence � essence!", + "keywords": ["modpack", "motor", "impair", "impair-width", "width"] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Gas Engine 3-Wide", "description": "Il s�agit d�un moteur � essence de la taille d�un moteur �lectrique. Id�al pour les cr�ations � largeur irr�guli�re � essence � essence!", "keywords": ["modpack", "motor", "impair", "impair-width", "width"] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico thruster - Low power [#ffff00OBSOLÈTE#ffffff]", + "description": "Des propulseurs en man�uvre, ou tout simplement un propulseur basse consommation", + "keywords": ["modpack", "rocket", "booster", "boost", "force", "�chappement"] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico thruster - Low power", "description": "Des propulseurs en man�uvre, ou tout simplement un propulseur basse consommation", "keywords": ["modpack", "rocket", "booster", "boost", "force", "�chappement"] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro Thruster [#ffff00OBSOLÈTE#ffffff]", + "description": "Micro Thruster avec plusieurs niveaux de puissance", + "keywords": ["modpack", "rocket", "booster", "boost", "force", "�chappement"] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro Thruster", "description": "Micro Thruster avec plusieurs niveaux de puissance", diff --git a/Gui/Language/German/inventoryDescriptions.json b/Gui/Language/German/inventoryDescriptions.json index 508f65c..ae41694 100644 --- a/Gui/Language/German/inventoryDescriptions.json +++ b/Gui/Language/German/inventoryDescriptions.json @@ -170,24 +170,48 @@ // engines "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Motor Feder [#ffff00VERALTET#ffffff]", + "description": "Dieses Teil ist ein Motor! Setze diesen Motor auf ein ein Lager und verbinde ihn damit! Platziere Rohre an einem Ende wo das Rad (und dessen Lenkung) sein wird. Nutze die andere Seite um die Bewegungsfreiheit zu begrenzen. Pass die Motorstärke an um die Federkraft einzustellen.", + "keywords": ["modpack", "motor", "Federung", "Feder", "Federung", "Winkel", " regler", "Controller", "Steuerung" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Motor Feder", "description": "Dieses Teil ist ein Motor! Setze diesen Motor auf ein ein Lager und verbinde ihn damit! Platziere Rohre an einem Ende wo das Rad (und dessen Lenkung) sein wird. Nutze die andere Seite um die Bewegungsfreiheit zu begrenzen. Pass die Motorstärke an um die Federkraft einzustellen.", "keywords": ["modpack", "motor", "Federung", "Feder", "Federung", "Winkel", " regler", "Controller", "Steuerung" ] }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Verbrennungsmotor (3 Böcke Breit) [#ffff00VERALTET#ffffff]", + "description": "Ein Verbrennungsmotor, welcher der Größe eines Elektromotors entspricht. Perfekt geeignet für ausbalancierte, ungerade breite Kreationen!", + "keywords": ["modpack", "motor", "ungerade", "ungerade breit", " breit", "lang" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Verbrennungsmotor (3 Böcke Breit)", "description": "Ein Verbrennungsmotor, welcher der Größe eines Elektromotors entspricht. Perfekt geeignet für ausbalancierte, ungerade breite Kreationen!", "keywords": ["modpack", "motor", "ungerade", "ungerade breit", " breit", "lang" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico-Schubdüse (geringer Schub) [#ffff00VERALTET#ffffff]", + "description": "Als Manövrierschubdüse oder Schubdüse mit geringer Schubkraft nutzbar.", + "keywords": [ "modpack", "Rakete", "booster", "boost", "Schub", "Düse", "Triebwerk", "Kraft", "Auspuff", "Leistung" , "Pico", "gering" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico-Schubdüse (geringer Schub)", "description": "Als Manövrierschubdüse oder Schubdüse mit geringer Schubkraft nutzbar.", "keywords": [ "modpack", "Rakete", "booster", "boost", "Schub", "Düse", "Triebwerk", "Kraft", "Auspuff", "Leistung" , "Pico", "gering" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro-Schubdüse [#ffff00VERALTET#ffffff]", + "description": "Micro-Schubdüse mit mehreren Leistungsstufen.", + "keywords": [ "modpack", "Rakete", "booster", "boost", "Schub", "Düse", "Triebwerk", "Kraft", "Auspuff", "Leistung", "Micro" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro-Schubdüse", "description": "Micro-Schubdüse mit mehreren Leistungsstufen.", diff --git a/Gui/Language/Italian/inventoryDescriptions.json b/Gui/Language/Italian/inventoryDescriptions.json index 7a552f5..19fffa5 100644 --- a/Gui/Language/Italian/inventoryDescriptions.json +++ b/Gui/Language/Italian/inventoryDescriptions.json @@ -170,24 +170,48 @@ // engines "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Motore per Sospensione [#ffff00DEPRECATA#ffffff]", + "description": "Questo blocco è un motore! Metti questo blocco su un cuscinetto e connetti questo motore al cuscinetto! Metti dei tubi alla fine di dove la ruota (e lo sterzo) sarà posizionata, e usa l'altro capo per limitare la gamma. Imposta la potenza di questo motore per avere una sospensione lenta o solida.", + "keywords": [ "modpack", "motore", "sospensione", "molla", "angolo", "controllore" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Motore per Sospensione", "description": "Questo blocco è un motore! Metti questo blocco su un cuscinetto e connetti questo motore al cuscinetto! Metti dei tubi alla fine di dove la ruota (e lo sterzo) sarà posizionata, e usa l'altro capo per limitare la gamma. Imposta la potenza di questo motore per avere una sospensione lenta o solida.", "keywords": [ "modpack", "motore", "sospensione", "molla", "angolo", "controllore" ] }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Motore a Gas - Largo 3 [#ffff00DEPRECATA#ffffff]", + "description": "È un motore a gas largo come un motore elettrico. Perfetto per creazioni di larghezza dispari!", + "keywords": [ "modpack", "motore", "dispari", "largo" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Motore a Gas - Largo 3", "description": "È un motore a gas largo come un motore elettrico. Perfetto per creazioni di larghezza dispari!", "keywords": [ "modpack", "motore", "dispari", "largo" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Pico Propulsore - Bassa Potenza [#ffff00DEPRECATA#ffffff]", + "description": "Propulsori di manovra, oppure soltanto dei propulsori a bassa potenza", + "keywords": [ "modpack", "razzo", "propulsore", "forza", "marmitta" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Pico Propulsore - Bassa Potenza", "description": "Propulsori di manovra, oppure soltanto dei propulsori a bassa potenza", "keywords": [ "modpack", "razzo", "propulsore", "forza", "marmitta" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "Mini Propulsore - 1x4 [#ffff00DEPRECATA#ffffff]", + "description": "Un propulsore più piccolo. Ottimo per missili!", + "keywords": [ "modpack", "razzo", "propulsore", "forza", "marmitta" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "Mini Propulsore - 1x4", "description": "Un propulsore più piccolo. Ottimo per missili!", diff --git a/Gui/Language/Japanese/inventoryDescriptions.json b/Gui/Language/Japanese/inventoryDescriptions.json index 69f08ae..7db9175 100644 --- a/Gui/Language/Japanese/inventoryDescriptions.json +++ b/Gui/Language/Japanese/inventoryDescriptions.json @@ -94,6 +94,12 @@ "keywords": [ "modpack", "modopaku", "モドパク", "サスペンション" ] }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "エンジン サスペンション [#ffff00非推奨#ffffff]", + "description": "この 部分 は エンジンです! この 部品 を ベアリング に 取り付け、 この エンジン を ベアリング に 接続し ます! ホイール (および ステアリング) が 行く 一方 の 端 に いくつ か の パイプ を 接続 し、 もう 一方 の 端 を 使用し て 可動 範囲 を 制限し ます。 緩い または しっかり した エンジン サスペンション の ため に、 この エンジン の 出力 を 設定 します。", + "keywords": [ "modpack", "modopaku", "モドパク", "モーター", "サスペンション", "サスペンション", "角度", "コントローラー" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "エンジン サスペンション", "description": "この 部分 は エンジンです! この 部品 を ベアリング に 取り付け、 この エンジン を ベアリング に 接続し ます! ホイール (および ステアリング) が 行く 一方 の 端 に いくつ か の パイプ を 接続 し、 もう 一方 の 端 を 使用し て 可動 範囲 を 制限し ます。 緩い または しっかり した エンジン サスペンション の ため に、 この エンジン の 出力 を 設定 します。", @@ -176,18 +182,36 @@ // engines "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "ガスエンジン 3x [#ffff00非推奨#ffffff]", + "description": "電気 エンジン の サイズ に 適合す る ガス エンジン です。 バランス の 取れた ガス 駆動 の 奇数 幅 の 作成に 最適です!", + "keywords": [ "modpack", "modopaku", "モドパク", "モーター", "奇数幅" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "ガスエンジン 3x", "description": "電気 エンジン の サイズ に 適合す る ガス エンジン です。 バランス の 取れた ガス 駆動 の 奇数 幅 の 作成に 最適です!", "keywords": [ "modpack", "modopaku", "モドパク", "モーター", "奇数幅" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "ピコ スラスタ [#ffff00非推奨#ffffff]", + "description": "操縦 スラスタ または 単なる 低出力 スラスタ", + "keywords": [ "modpack", "modopaku", "モドパク", "ロケット", "力", "排気" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "ピコ スラスタ", "description": "操縦 スラスタ または 単なる 低出力 スラスタ", "keywords": [ "modpack", "modopaku", "モドパク", "ロケット", "力", "排気" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "小さな スラスタ 1x1 [#ffff00非推奨#ffffff]", + "description": "より 多く の 出力 レベル を 持つ マイクロスラスタ", + "keywords": [ "modpack", "modopaku", "モドパク", "ロケット", "力", "排気" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "小さな スラスタ 1x1", "description": "より 多く の 出力 レベル を 持つ マイクロスラスタ", diff --git a/Gui/Language/Russian/inventoryDescriptions.json b/Gui/Language/Russian/inventoryDescriptions.json index d086568..879732e 100644 --- a/Gui/Language/Russian/inventoryDescriptions.json +++ b/Gui/Language/Russian/inventoryDescriptions.json @@ -188,24 +188,48 @@ // engines "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Двигатель-подвеска [#ffff00УСТАРЕЛ#ffffff]", + "description": "Эта деталь является двигателем! Прикрепите эту деталь на подшипник и подключите к подшипнику! Подключите трубы к одному концу где ваше колесо (и поворотный механизм) будет стоять, и используйте другой конец чтобы ограничить движение. Установите мощность двигателя если хотите сделать подвеску мягкой или жесткой.", + "keywords": [ "модпак", "мотор", "подвеска", "пружина", "угол", "контроллер" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Двигатель-подвеска", "description": "Эта деталь является двигателем! Прикрепите эту деталь на подшипник и подключите к подшипнику! Подключите трубы к одному концу где ваше колесо (и поворотный механизм) будет стоять, и используйте другой конец чтобы ограничить движение. Установите мощность двигателя если хотите сделать подвеску мягкой или жесткой.", "keywords": [ "модпак", "мотор", "подвеска", "пружина", "угол", "контроллер" ] }, "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Бензиновый двигатель 3x [#ffff00УСТАРЕЛ#ffffff]", + "description": "Этот бензиновый двигаетль схож по размеру с электрическим двигателем. Идеален для построек с нечетной шириной!", + "keywords": [ "модпак", "мотор", "нечётный", "нечётная ширина", "ширина" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Бензиновый двигатель 3x", "description": "Этот бензиновый двигаетль схож по размеру с электрическим двигателем. Идеален для построек с нечетной шириной!", "keywords": [ "модпак", "мотор", "нечётный", "нечётная ширина", "ширина" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Ускоритель - малая мощность [#ffff00УСТАРЕЛ#ffffff]", + "description": "Маневровые ускоритель, или просто маломощный ускоритель", + "keywords": [ "модпак", "ракета", "ускоритель", "ускорение", "сила", "выхлоп" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Ускоритель - малая мощность", "description": "Маневровые ускоритель, или просто маломощный ускоритель", "keywords": [ "модпак", "ракета", "ускоритель", "ускорение", "сила", "выхлоп" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Ускоритель [#ffff00УСТАРЕЛ#ffffff]", + "description": "Маленький ускоритель, с более большим количеством уровней тяги", + "keywords": [ "модпак", "ракета", "ускоритель", "ускорение", "сила", "выхлоп" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Ускоритель", "description": "Маленький ускоритель, с более большим количеством уровней тяги", diff --git a/Gui/Language/Spanish/inventoryDescriptions.json b/Gui/Language/Spanish/inventoryDescriptions.json index 8ed6fbf..ef8bf1e 100644 --- a/Gui/Language/Spanish/inventoryDescriptions.json +++ b/Gui/Language/Spanish/inventoryDescriptions.json @@ -94,6 +94,12 @@ "keywords": [ "modpack", "resorte" ] }, "93e08947-be6d-436c-a64f-932727428c89": + { + "title": "Suspensión del motor [#ffff00OBSOLETA#ffffff]", + "description": "¡Esta parte es un motor! ¡Ponga esta parte en un rodamiento y conecte este motor al rodamiento! Conecte algunas tuberías a un extremo donde irá la rueda (y la dirección), y use el otro extremo para limitar el alcance de movimiento. Establezca la potencia de este motor para una suspensión del motor suelta o firme", + "keywords": [ "modpack", "motor", "suspensión", "resorte", "ángulo", "controlador" ] + }, + "b69bf080-2467-4360-9677-72cfd48806c9": { "title": "Suspensión del motor", "description": "¡Esta parte es un motor! ¡Ponga esta parte en un rodamiento y conecte este motor al rodamiento! Conecte algunas tuberías a un extremo donde irá la rueda (y la dirección), y use el otro extremo para limitar el alcance de movimiento. Establezca la potencia de este motor para una suspensión del motor suelta o firme", @@ -176,18 +182,36 @@ // motores "f55aa240-d4b2-48cc-9c6b-a90fce299bf4": + { + "title": "Motor de gas de 3 anchos [#ffff00OBSOLETA#ffffff]", + "description": "Es un motor de gasolina que se ajusta al tamaño de un motor eléctrico. Perfecto para equilibrar creaciones de gas de ancho extraño", + "keywords": [ "modpack", "motor", "impar", "ancho impar", "ancho" ] + }, + "70cbacf2-ec5a-471f-9896-0ee944c581d1": { "title": "Motor de gas de 3 anchos", "description": "Es un motor de gasolina que se ajusta al tamaño de un motor eléctrico. Perfecto para equilibrar creaciones de gas de ancho extraño", "keywords": [ "modpack", "motor", "impar", "ancho impar", "ancho" ] }, "c394b6e8-554c-4074-a119-ab2fec55e456": + { + "title": "Cohete Pico - Baja potencia [#ffff00OBSOLETA#ffffff]", + "description": "Propulsores de maniobra, o simplemente un propulsor de baja potencia", + "keywords": [ "modpack", "cohete", "refuerzo", "impulso", "fuerza", "escape" ] + }, + "9235b582-fc25-48a8-a807-68d98755d077": { "title": "Cohete Pico - Baja potencia", "description": "Propulsores de maniobra, o simplemente un propulsor de baja potencia", "keywords": [ "modpack", "cohete", "refuerzo", "impulso", "fuerza", "escape" ] }, "036fbe44-45df-11e6-beb8-9e71128cae77": + { + "title": "1x1 Micro Cohete [#ffff00OBSOLETA#ffffff]", + "description": "Micro Cohete con más niveles de potencia", + "keywords": [ "modpack", "cohete", "refuerzo", "impulso", "fuerza", "escape" ] + }, + "a07a3673-a446-44a3-b16d-abb732c7a525": { "title": "1x1 Micro Cohete", "description": "Micro Cohete con más niveles de potencia", diff --git a/Gui/Layouts/CounterBlockGui.layout b/Gui/Layouts/CounterBlockGui.layout new file mode 100644 index 0000000..0439402 --- /dev/null +++ b/Gui/Layouts/CounterBlockGui.layout @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gui/Layouts/MathBlock.layout b/Gui/Layouts/MathBlock.layout index e1c4532..ef86723 100644 --- a/Gui/Layouts/MathBlock.layout +++ b/Gui/Layouts/MathBlock.layout @@ -1,202 +1,202 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gui/Layouts/Orienter.layout b/Gui/Layouts/Orienter.layout index 30a668b..ab49ea5 100644 --- a/Gui/Layouts/Orienter.layout +++ b/Gui/Layouts/Orienter.layout @@ -1,206 +1,206 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gui/Layouts/SmartSensor.layout b/Gui/Layouts/SmartSensor.layout index 9fe3205..b60fc1e 100644 --- a/Gui/Layouts/SmartSensor.layout +++ b/Gui/Layouts/SmartSensor.layout @@ -1,79 +1,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Gui/Layouts/XOMeter.layout b/Gui/Layouts/XOMeter.layout index eee9d7b..24f74c6 100644 --- a/Gui/Layouts/XOMeter.layout +++ b/Gui/Layouts/XOMeter.layout @@ -1,119 +1,119 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Objects/Database/ShapeSets/interactive.json b/Objects/Database/ShapeSets/interactive.json index a87e70d..2a981eb 100644 --- a/Objects/Database/ShapeSets/interactive.json +++ b/Objects/Database/ShapeSets/interactive.json @@ -310,7 +310,7 @@ "stackSize": 5 }, { - "uuid": "93e08947-be6d-436c-a64f-932727428c89", + "uuid": "93e08947-be6d-436c-a64f-932727428c89", //OLD Engine Suspension "renderable": { "lodList": [ { @@ -367,6 +367,50 @@ ], "effect": "GasEngine - Level 1" }, + "qualityLevel": 4, + "showInInventory": false + }, + { + "uuid": "b69bf080-2467-4360-9677-72cfd48806c9", //NEW Engine Suspension + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$MOD_DATA/Objects/Textures/mod_decor_cone_dif.png", + "$MOD_DATA/Objects/Textures/mod_decor_cone_asg.png", + "$GAME_DATA/Textures/nonor_nor.tga" + ], + "material": "DifAsg" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/mjm_EngineSuspension.mesh" + } + ] + }, + "rotationSet": "PropY", + "color": "df7f00", + "hull": { + "x": 1, "y": 1, "z": 3, + "pointList": [ + { "x": 0.0, "y": 1.0, "z": 1.0 }, + { "x": 1.0, "y": 0.0, "z": 1.0 }, + { "x": 0.0, "y": -1.0, "z": 1.0 }, + { "x": -1.0, "y": 0.0, "z": 1.0 }, + { "x": -0.1, "y": 1.0, "z": -1.0 }, + { "x": 0.1, "y": 1.0, "z": -1.0 }, + { "x": 0.1, "y": -1.0, "z": -1.0 }, + { "x": -0.1, "y": -1.0, "z": -1.0 } + ] + }, + "density": 1250.0, + "physicsMaterial": "Metal", + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModGasEngine.lua", + "classname": "GasEngine", + "data": {} + }, "qualityLevel": 4 }, { @@ -1041,7 +1085,7 @@ "flammable": false }, { - "uuid": "f55aa240-d4b2-48cc-9c6b-a90fce299bf4", + "uuid": "f55aa240-d4b2-48cc-9c6b-a90fce299bf4", //OLD Gas Engine 3-Wide "renderable": { "lodList": [ { @@ -1078,10 +1122,42 @@ ], "effect": "GasEngine - Level 1" }, + "qualityLevel": 5, + "showInInventory": false + }, + { + "uuid": "70cbacf2-ec5a-471f-9896-0ee944c581d1", //NEW Gas Engine 3-Wide + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginegas_dif.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginegas_asg.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginegas_nor.tga" + ], + "material": "DifAsgNor" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/mjm_EngineGasOdd.mesh" + } + ] + }, + "rotationSet": "PropYf", + "color": "df7f00", + "box": { "x": 3, "y": 2, "z": 2 }, + "density": 1250.0, + "physicsMaterial": "Metal", + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModGasEngine.lua", + "classname": "GasEngine", + "data": {} + }, "qualityLevel": 5 }, { - "uuid": "c394b6e8-554c-4074-a119-ab2fec55e456", + "uuid": "c394b6e8-554c-4074-a119-ab2fec55e456", //OLD pico thruster "renderable": { "lodList": [ { @@ -1136,11 +1212,56 @@ "sticky": "-Z", "physicsMaterial": "Mechanical", "density": 250.0, + "qualityLevel": 4, + "showInInventory": false + }, + { + "uuid": "9235b582-fc25-48a8-a807-68d98755d077", //NEW pico thruster + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$MOD_DATA/Objects/Textures/mod_decor_cone_dif.png", + "$MOD_DATA/Objects/Textures/mod_decor_cone_asg.png", + "$MOD_DATA/Objects/Textures/mod_decor_cone_nor.png" + ], + "material": "DifAsgNor" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/mjm_PicoThruster.mesh" + } + ] + }, + "color": "df7f00", + "hull": { + "x": 1, "y": 1, "z": 1, + "margin": 0.0, + "pointList": [ + { "x": 1.0, "y": 0.0, "z": -1.0 }, + { "x": 0.0, "y": 1.0, "z": -1.0 }, + { "x": -1.0, "y": 0.0, "z": -1.0 }, + { "x": 0.0, "y": -1.0, "z": -1.0 }, + { "x": 1.0, "y": 0.0, "z": -0.8 }, + { "x": 0.0, "y": 1.0, "z": -0.8 }, + { "x": -1.0, "y": 0.0, "z": -0.8 }, + { "x": 0.0, "y": -1.0, "z": -0.8 } + ] + }, + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModThruster.lua", + "classname": "ModThruster" + }, + "rotationSet": "PropZ", + "sticky": "-Z", + "physicsMaterial": "Mechanical", + "density": 250.0, "qualityLevel": 4 }, { "legacyId": 3222, - "uuid": "036fbe44-45df-11e6-beb8-9e71128cae77", + "uuid": "036fbe44-45df-11e6-beb8-9e71128cae77", //OLD 1x1 Micro thruster "renderable": { "lodList": [ { @@ -1185,6 +1306,41 @@ "sticky": "-Z", "physicsMaterial": "Mechanical", "density": 250.0, + "qualityLevel": 4, + "showInInventory": false + }, + { + "uuid": "a07a3673-a446-44a3-b16d-abb732c7a525", //NEW 1x1 Micro thruster + "renderable": { + "lodList": [ + { + "subMeshList": [ + { + "textureList": [ + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginejet_dif.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginejet_asg.tga", + "$GAME_DATA/Objects/Textures/interactive/obj_interactive_enginejet_nor.tga" + ], + "material": "3PoseAnimDifAsgNor" + } + ], + "mesh": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_off.obj", + "pose0": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_off01.obj", + "pose1": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_on.obj", + "pose2": "$MOD_DATA/Objects/Mesh/obj_interactive_thruster_on01.obj" + } + ] + }, + "color": "007fdf", + "box": { "x": 1, "y": 1, "z": 1 }, + "scripted": { + "filename": "$MOD_DATA/Scripts/interactable/Locomotion/ModThruster.lua", + "classname": "ModThruster" + }, + "rotationSet": "PropZ", + "sticky": "-Z", + "physicsMaterial": "Mechanical", + "density": 250.0, "qualityLevel": 4 }, { diff --git a/Scripts/interactable/BlockSpawner.lua b/Scripts/interactable/BlockSpawner.lua index 23fc318..800f73c 100644 --- a/Scripts/interactable/BlockSpawner.lua +++ b/Scripts/interactable/BlockSpawner.lua @@ -79,7 +79,7 @@ function BlockSpawner.printDescription() end function BlockSpawner.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") + local _useKey = sm.gui.getKeyBinding("Use", true) sm.gui.setInteractionText("Press", _useKey, "to print color input/output in chat") return true end diff --git a/Scripts/interactable/Locomotion/Gimball.lua b/Scripts/interactable/Locomotion/Gimball.lua index 92bc6e5..4ea7b54 100644 --- a/Scripts/interactable/Locomotion/Gimball.lua +++ b/Scripts/interactable/Locomotion/Gimball.lua @@ -10,7 +10,7 @@ print("loading Gimball.lua") Gimball = class() Gimball.maxParentCount = -1 Gimball.maxChildCount = 0 -Gimball.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +Gimball.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.gasoline Gimball.connectionOutput = sm.interactable.connectionType.none Gimball.colorNormal = sm.color.new( 0x009999ff )--sm.color.new( 0x844040ff ) Gimball.colorHighlight = sm.color.new( 0x11B2B2ff )-- = sm.color.new( 0xb25959ff ) @@ -25,23 +25,71 @@ function Gimball.server_init( self ) self.power = 0 self.smode = 0 self.direction = sm.vec3.new(0,0,1) + + mp_fuel_initialize(self, obj_consumable_gas, 0.35) local stored = self.storage:load() if stored then - self.smode = stored - 1 + local stored_type = type(stored) + if stored_type == "number" then + self.smode = stored - 1 + elseif stored_type == "table" then + self.smode = stored[1] - 1 + self.sv_fuel_points = stored[2] + end end + + self.sv_saved_fuel_points = self.sv_fuel_points end function Gimball.server_onRefresh( self ) self:server_init() end -function Gimball.server_onFixedUpdate( self ) - if self.power ~= 0 and math.abs(self.power) ~= math.huge then +function Gimball.server_onFixedUpdate( self, dt ) + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_consume = mp_fuel_canConsumeFuel(self, l_container) + + if can_activate and self.power ~= 0 and math.abs(self.power) ~= math.huge then sm.physics.applyImpulse(self.shape, self.direction*math.abs(self.power), true) - --print(self.direction) + + if can_consume then + mp_fuel_consumeFuelPoints(self, l_container, self.power, dt) + end + end + + if self.sv_saved_can_activate ~= can_activate then + self.sv_saved_can_activate = can_activate + self.network:setClientData(can_activate) + end + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then + self.sv_saved_fuel_points = self.sv_fuel_points + self.sv_fuel_save_timer = 1 + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfFuel") + end end + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.storage:save({ self.smode+1, self.sv_fuel_points }) + end + end +end + +function Gimball:client_onClientDataUpdate(params) + self.cl_can_activate = params end + +function Gimball:client_onOutOfFuel() + mp_fuel_displayOutOfFuelMessage(self) +end + function Gimball.client_onCreate(self) self.shootEffect = sm.effect.createEffect( "Thruster - Level 2", self.interactable ) self.shootEffect:setOffsetPosition(sm.vec3.zero()) @@ -61,32 +109,48 @@ end function Gimball.client_onDestroy(self) self.shootEffect:stop() end + function Gimball.client_onInteract(self, character, lookAt) if not lookAt or character:getLockingInteractable() then return end self.network:sendToServer("server_changemode", character:isCrouching()) end + function Gimball.server_changemode(self, crouch) self.smode = (self.smode + (crouch and -1 or 1)) % 4 - self.storage:save(self.smode+1) + self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) self.network:sendToClients("client_mode", {mode = self.smode, sound = true}) end + function Gimball.server_requestmode(self) self.network:sendToClients("client_mode", {mode = self.smode, sound = false}) end + function Gimball.client_mode(self, data) if data.sound then sm.audio.play("ConnectTool - Rotate", self.shape:getWorldPosition()) end self.mode = data.mode end + +local default_hypertext = "

%s

" function Gimball.client_canInteract(self) - sm.gui.setInteractionText("Press", sm.gui.getKeyBinding("Use"), "to change mode") - sm.gui.setInteractionText("Current mode: "..self.modes[self.mode+1]) + local use_key = sm.gui.getKeyBinding("Use") + local crawl_key = sm.gui.getKeyBinding("Crawl") + + local use_hyper = default_hypertext:format(use_key) + local crawl_and_use_hyper = default_hypertext:format(crawl_key.." + "..use_key) + + sm.gui.setInteractionText("Press", use_hyper, "or", crawl_and_use_hyper, "to change mode") + + local cur_mode_hyper = default_hypertext:format("Mode: "..self.modes[self.mode+1]) + sm.gui.setInteractionText("", cur_mode_hyper) + return true end +local gb_logic_and_power = bit.bor(sm.interactable.connectionType.logic, sm.interactable.connectionType.power) function Gimball.client_onFixedUpdate(self, dt) - local parents = self.interactable:getParents() + local parents = self.interactable:getParents(gb_logic_and_power) local power = #parents>0 and 100 or 0 local hasnumber = false local logicinput = 1 @@ -178,9 +242,15 @@ function Gimball.client_onFixedUpdate(self, dt) end end - self.power = power * logicinput * canfire - if math.abs(self.power) == math.huge or self.power ~= self.power then self.power = 0 end - + if self.cl_can_activate then + self.power = power * logicinput * canfire + else + self.power = 0 + end + + if math.abs(self.power) == math.huge or self.power ~= self.power then + self.power = 0 + end if self.mode == 0 then if ws then self.angleX = ws*90 end @@ -268,10 +338,10 @@ function Gimball.client_onFixedUpdate(self, dt) ]] - if false then --visualise x and z + --[[if false then --visualise x and z sm.particle.createParticle("construct_welding", self.shape.worldPosition + localX) sm.particle.createParticle("construct_welding", self.shape.worldPosition + localZ) - end + end]] -- direction to pose translation: local localvec = getLocal(self.shape, self.direction*-1) diff --git a/Scripts/interactable/Locomotion/ModGasEngine.lua b/Scripts/interactable/Locomotion/ModGasEngine.lua new file mode 100644 index 0000000..9bafeb5 --- /dev/null +++ b/Scripts/interactable/Locomotion/ModGasEngine.lua @@ -0,0 +1,648 @@ +-- GasEngine.lua -- +dofile("$SURVIVAL_DATA/Scripts/game/survival_constants.lua") +dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") + +dofile("$SURVIVAL_DATA/Scripts/util.lua") + +GasEngine = class() +GasEngine.maxParentCount = 2 +GasEngine.maxChildCount = 255 +GasEngine.connectionInput = sm.interactable.connectionType.logic + sm.interactable.connectionType.power + sm.interactable.connectionType.gasoline +GasEngine.connectionOutput = sm.interactable.connectionType.bearing +GasEngine.colorNormal = sm.color.new( 0xff8000ff ) +GasEngine.colorHighlight = sm.color.new( 0xff9f3aff ) +GasEngine.poseWeightCount = 1 + +local Gears = { + { power = 0 }, + { power = 30 }, + { power = 60 }, + { power = 90 }, + { power = 150 }, -- 1 + { power = 240 }, + { power = 390 }, -- 2 + { power = 630 }, + { power = 1020 }, -- 3 + { power = 1650 }, + { power = 2670 }, -- 4 + { power = 4320 }, + { power = 6990 }, -- 5 +} + +local GasEngine3WideGears = { + { power = 0 }, + { power = 8 }, + { power = 16 }, + { power = 32 }, + { power = 64 }, + { power = 128 }, + { power = 256 }, + { power = 512 }, + { power = 1024 } +} + +local EngineSuspensionGears = { + { power = 0 }, + { power = 8 }, + { power = 16 }, + { power = 32 }, + { power = 64 }, + { power = 128 }, + { power = 256 }, + { power = 512 }, + { power = 1024 }, + { power = 2048 }, + { power = 4096 }, + { power = 8192 }, + { power = 16384 }, + { power = 32768 }, + { power = 65536 }, + { power = 131072 }, + { power = 262144 } +} + +local EngineLevels = { + ["70cbacf2-ec5a-471f-9896-0ee944c581d1"] = { --Gas Engine 3-Wide + gears = GasEngine3WideGears, + gearCount = #GasEngine3WideGears, + title = "Modpack Continuation", + bearingCount = 5, + pointsPerFuel = 15000, + effect = "GasEngine - Level 1" + }, + ["b69bf080-2467-4360-9677-72cfd48806c9"] = { --Engine Suspension + gears = EngineSuspensionGears, + gearCount = #EngineSuspensionGears, + title = "Modpack Continuation", + bearingCount = 5, + pointsPerFuel = 11000, + effect = "GasEngine - Level 1" + } +} + +local RadPerSecond_100KmPerHourOn3BlockDiameterTyres = 74.074074 +local RadPerSecond_1MeterPerSecondOn3BlockDiameterTyres = 2.6666667 + +--[[ Server ]] + +function GasEngine.server_onCreate( self ) + local container = self.shape.interactable:getContainer( 0 ) + if not container then + container = self.shape:getInteractable():addContainer( 0, 1, 10 ) + end + container:setFilters( { obj_consumable_gas } ) + + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + assert(level) + if level.fn then + level.fn( self ) + end + + self.scrapOffset = 0 + self.pointsPerFuel = level.pointsPerFuel + self.gears = level.gears + self:server_init() +end + +function GasEngine.server_onRefresh( self ) + self:server_init() +end + +function GasEngine.server_init( self ) + + self.saved = self.storage:load() + if self.saved == nil then + self.saved = {} + end + if self.saved.gearIdx == nil then + self.saved.gearIdx = 1 + end + if self.saved.fuelPoints == nil then + self.saved.fuelPoints = 0 + end + + self.power = 0 + self.motorVelocity = 0 + self.motorImpulse = 0 + self.fuelPoints = self.saved.fuelPoints + self.hasFuel = false + self.dirtyStorageTable = false + self.dirtyClientTable = false + + self:sv_setGear( self.saved.gearIdx ) +end + +function GasEngine.sv_setGear( self, gearIdx ) + self.saved.gearIdx = gearIdx + self.dirtyStorageTable = true + self.dirtyClientTable = true +end + +function GasEngine.sv_updateFuelStatus( self, fuelContainer ) + + if self.saved.fuelPoints ~= self.fuelPoints then + self.saved.fuelPoints = self.fuelPoints + self.sv_fuel_save_timer = 1 + end + + local hasFuel = ( self.fuelPoints > 0 ) or sm.container.canSpend( fuelContainer, obj_consumable_gas, 1 ) + if self.hasFuel ~= hasFuel then + self.hasFuel = hasFuel + self.dirtyClientTable = true + end + +end + +function GasEngine.controlEngine( self, direction, active, timeStep, gearIdx ) + direction = clamp( direction, -1, 1 ) + if ( math.abs( direction ) > 0 or not active ) then + self.power = self.power + timeStep + else + self.power = self.power - timeStep + end + self.power = clamp( self.power, 0, 1 ) + + if direction == 0 and active then + self.power = 0 + end + + self.motorVelocity = ( active and direction or 0 ) * RadPerSecond_100KmPerHourOn3BlockDiameterTyres + self.motorImpulse = ( active and self.power or 2 ) * self.gears[gearIdx].power +end + +function GasEngine.getInputs( self ) + + local parents = self.interactable:getParents() + local active = true + local direction = 1 + local fuelContainer = nil + local hasInput = false + if parents[2] then + if parents[2]:hasOutputType( sm.interactable.connectionType.logic ) then + active = parents[2]:isActive() + hasInput = true + end + if parents[2]:hasOutputType( sm.interactable.connectionType.power ) then + active = parents[2]:isActive() + direction = parents[2]:getPower() + hasInput = true + end + if parents[2]:hasOutputType( sm.interactable.connectionType.gasoline ) then + fuelContainer = parents[2]:getContainer( 0 ) + end + end + if parents[1] then + if parents[1]:hasOutputType( sm.interactable.connectionType.logic ) then + active = parents[1]:isActive() + hasInput = true + end + if parents[1]:hasOutputType( sm.interactable.connectionType.power ) then + active = parents[1]:isActive() + direction = parents[1]:getPower() + hasInput = true + end + if parents[1]:hasOutputType( sm.interactable.connectionType.gasoline ) then + fuelContainer = parents[1]:getContainer( 0 ) + end + end + + return active, direction, fuelContainer, hasInput + +end + +function GasEngine.server_onFixedUpdate( self, timeStep ) + + -- Check engine connections + local hadInput = self.hasInput == nil and true or self.hasInput --Pretend to have had input if nil to avoid starting engines at load + local active, direction, fuelContainer, hasInput = self:getInputs() + self.hasInput = hasInput + local useCreativeFuel = not sm.game.getEnableFuelConsumption() and fuelContainer == nil + + -- Check fuel container + if not fuelContainer or fuelContainer:isEmpty() then + fuelContainer = self.shape.interactable:getContainer( 0 ) + end + + -- Check bearings + local bearings = {} + local joints = self.interactable:getJoints() + for _, joint in ipairs( joints ) do + if joint:getType() == "bearing" then + bearings[#bearings+1] = joint + end + end + + -- Update motor gear when a steering is added + if not hadInput and hasInput then + if self.saved.gearIdx == 1 then + self:sv_setGear( 2 ) + end + end + + -- Consume fuel for fuel points + local canSpend = false + if self.fuelPoints <= 0 then + canSpend = sm.container.canSpend( fuelContainer, obj_consumable_gas, 1 ) + end + + -- Control engine + if self.fuelPoints > 0 or canSpend or useCreativeFuel then + + if hasInput == false then + self.power = 1 + self:controlEngine( 1, true, timeStep, self.saved.gearIdx ) + else + self:controlEngine( direction, active, timeStep, self.saved.gearIdx ) + end + + if not useCreativeFuel then + -- Consume fuel points + local appliedImpulseCost = 0.015625 + local fuelCost = 0 + for _, bearing in ipairs( bearings ) do + if bearing.appliedImpulse * bearing.angularVelocity < 0 then -- No added fuel cost if the bearing is decelerating + fuelCost = fuelCost + math.abs( bearing.appliedImpulse ) * appliedImpulseCost + end + end + fuelCost = math.min( fuelCost, math.sqrt( fuelCost / 7.5 ) * 7.5 ) + + self.fuelPoints = self.fuelPoints - fuelCost + + if self.fuelPoints <= 0 and fuelCost > 0 then + sm.container.beginTransaction() + sm.container.spend( fuelContainer, obj_consumable_gas, 1, true ) + if sm.container.endTransaction() then + self.fuelPoints = self.fuelPoints + self.pointsPerFuel + end + end + end + + else + self:controlEngine( 0, false, timeStep, self.saved.gearIdx ) + end + + -- Update rotational joints + for _, bearing in ipairs( bearings ) do + bearing:setMotorVelocity( self.motorVelocity, self.motorImpulse ) + end + + self:sv_updateFuelStatus( fuelContainer ) + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - timeStep + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.dirtyStorageTable = true + end + end + + -- Storage table dirty + if self.dirtyStorageTable then + self.storage:save( self.saved ) + self.dirtyStorageTable = false + end + + -- Client table dirty + if self.dirtyClientTable then + self.network:setClientData( { gearIdx = self.saved.gearIdx, engineHasFuel = self.hasFuel or useCreativeFuel, scrapOffset = self.scrapOffset } ) + self.dirtyClientTable = false + end +end + +--[[ Client ]] + +function GasEngine.client_onCreate( self ) + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + self.gears = level.gears + self.client_gearIdx = 1 + self.effect = sm.effect.createEffect( level.effect, self.interactable ) + self.engineHasFuel = false + self.scrapOffset = self.scrapOffset or 0 + self.power = 0 +end + +function GasEngine.client_onClientDataUpdate( self, params ) + + if self.gui then + if self.gui:isActive() and params.gearIdx ~= self.client_gearIdx then + self.gui:setSliderPosition("Setting", params.gearIdx - 1 ) + end + end + + self.client_gearIdx = params.gearIdx + self.interactable:setPoseWeight( 0, params.gearIdx / #self.gears ) + + if self.engineHasFuel and not params.engineHasFuel then + local character = sm.localPlayer.getPlayer().character + if character then + if ( self.shape.worldPosition - character.worldPosition ):length2() < 100 then + sm.gui.displayAlertText( "#{INFO_OUT_OF_FUEL}" ) + end + end + end + + if params.engineHasFuel then + self.effect:setParameter("gas", 0.0 ) + else + self.effect:setParameter("gas", 1.0 ) + end + + self.engineHasFuel = params.engineHasFuel + self.scrapOffset = params.scrapOffset +end + +function GasEngine.client_onDestroy( self ) + self.effect:destroy() + + if self.gui then + self.gui:close() + self.gui:destroy() + self.gui = nil + end +end + +function GasEngine.client_onFixedUpdate( self, timeStep ) + + local active, direction, externalFuelTank, hasInput = self:getInputs() + + + if self.gui then + self.gui:setVisible( "FuelContainer", externalFuelTank ~= nil ) + end + + if sm.isHost then + return + end + + -- Check bearings + local bearings = {} + local joints = self.interactable:getJoints() + for _, joint in ipairs( joints ) do + if joint:getType() == "bearing" then + bearings[#bearings+1] = joint + end + end + + -- Control engine + if self.engineHasFuel then + if hasInput == false then + self.power = 1 + + self:controlEngine( 1, true, timeStep, self.client_gearIdx ) + else + + self:controlEngine( direction, active, timeStep, self.client_gearIdx ) + end + else + self:controlEngine( 0, false, timeStep, self.client_gearIdx ) + end + + -- Update rotational joints + for _, bearing in ipairs( bearings ) do + bearing:setMotorVelocity( self.motorVelocity, self.motorImpulse ) + end +end + +function GasEngine.client_onUpdate( self, dt ) + + local active, direction = self:getInputs() + + self:cl_updateEffect( direction, active ) +end + +function GasEngine.client_onInteract( self, character, state ) + if state == true then + self.gui = sm.gui.createEngineGui() + + self.gui:setText( "Name", "#{CONTROLLER_ENGINE_GAS_TITLE}" ) + self.gui:setText( "Interaction", "#{CONTROLLER_ENGINE_INSTRUCTION}" ) + self.gui:setOnCloseCallback( "cl_onGuiClosed" ) + self.gui:setSliderCallback( "Setting", "cl_onSliderChange" ) + self.gui:setSliderData( "Setting", #self.gears, self.client_gearIdx - 1 ) + self.gui:setIconImage( "Icon", self.shape:getShapeUuid() ) + self.gui:setButtonCallback( "Upgrade", "cl_onUpgradeClicked" ) + + local fuelContainer = self.shape.interactable:getContainer( 0 ) + + if fuelContainer then + self.gui:setContainer( "Fuel", fuelContainer ) + end + + local _, _, externalFuelContainer, _ = self:getInputs() + if externalFuelContainer then + self.gui:setVisible( "FuelContainer", true ) + end + + if not sm.game.getEnableFuelConsumption() then + self.gui:setVisible( "BackgroundGas", false ) + self.gui:setVisible( "FuelGrid", false ) + end + + self.gui:open() + + local level = EngineLevels[ tostring( self.shape:getShapeUuid() ) ] + if level then + if level.upgrade then + local nextLevel = EngineLevels[ level.upgrade ] + self.gui:setData( "UpgradeInfo", { Gears = nextLevel.gearCount - level.gearCount, Bearings = nextLevel.bearingCount - level.bearingCount, Efficiency = 1 } ) + self.gui:setIconImage( "UpgradeIcon", sm.uuid.new( level.upgrade ) ) + else + self.gui:setVisible( "UpgradeIcon", false ) + self.gui:setData( "UpgradeInfo", nil ) + end + + self.gui:setVisible("SubTitle", false) + self.gui:setSliderRangeLimit( "Setting", level.gearCount ) + + if sm.game.getEnableUpgrade() and level.cost then + local inventory = sm.localPlayer.getPlayer():getInventory() + local availableKits = sm.container.totalQuantity( inventory, obj_consumable_component ) + local upgradeData = { cost = level.cost, available = availableKits } + self.gui:setData( "Upgrade", upgradeData ) + else + self.gui:setVisible( "Upgrade", false ) + end + end + end +end + +function GasEngine.client_getAvailableParentConnectionCount( self, connectionType ) + if bit.band( connectionType, bit.bor( sm.interactable.connectionType.logic, sm.interactable.connectionType.power ) ) ~= 0 then + return 1 - #self.interactable:getParents( bit.bor( sm.interactable.connectionType.logic, sm.interactable.connectionType.power ) ) + end + if bit.band( connectionType, sm.interactable.connectionType.gasoline ) ~= 0 then + return 1 - #self.interactable:getParents( sm.interactable.connectionType.gasoline ) + end + return 0 +end + +function GasEngine.client_getAvailableChildConnectionCount( self, connectionType ) + if connectionType ~= sm.interactable.connectionType.bearing then + return 0 + end + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + assert(level) + local maxBearingCount = level.bearingCount or 255 + return maxBearingCount - #self.interactable:getChildren( sm.interactable.connectionType.bearing ) +end + +function GasEngine.cl_onGuiClosed( self ) + self.gui:destroy() + self.gui = nil +end + +function GasEngine.cl_onSliderChange( self, sliderName, sliderPos ) + self.network:sendToServer( "sv_setGear", sliderPos + 1 ) + self.client_gearIdx = sliderPos + 1 +end + +function GasEngine.cl_onUpgradeClicked( self, buttonName ) + print( "upgrade clicked" ) + self.network:sendToServer("sv_n_tryUpgrade", sm.localPlayer.getPlayer() ) +end + +function GasEngine.cl_updateEffect( self, direction, active ) + local bearings = {} + local joints = self.interactable:getJoints() + for _, joint in ipairs( joints ) do + if joint:getType() == "bearing" then + bearings[#bearings+1] = joint + end + end + + local RadPerSecond_100KmPerHourOn3BlockDiameterTyres = 74.074074 + local avgImpulse = 0 + local avgVelocity = 0 + + if #bearings > 0 then + for _, currentBearing in ipairs( bearings ) do + avgImpulse = avgImpulse + math.abs( currentBearing.appliedImpulse ) + avgVelocity = avgVelocity + math.abs( currentBearing.angularVelocity ) + end + + avgImpulse = avgImpulse / #bearings + avgVelocity = avgVelocity / #bearings + + avgVelocity = math.min( avgVelocity, RadPerSecond_100KmPerHourOn3BlockDiameterTyres ) + end + + local impulseFraction = 0 + local velocityFraction = avgVelocity / ( RadPerSecond_100KmPerHourOn3BlockDiameterTyres / 1.2 ) + + if direction ~= 0 and self.gears[self.client_gearIdx].power > 0 then + impulseFraction = math.abs( avgImpulse ) / self.gears[self.client_gearIdx].power + end + + local maxRPM = 0.9 * (self.client_gearIdx / #self.gears) + local rpm = 0.1 + + if avgVelocity > 0 then + rpm = rpm + math.min( velocityFraction * maxRPM, maxRPM ) + end + + local engineLoad = 0 + + if direction ~= 0 then + engineLoad = impulseFraction - math.min( velocityFraction, 1.0 ) + end + + local onLift = self.shape:getBody():isOnLift() + if #self.interactable:getParents() == 0 then + if self.effect:isPlaying() == false and #bearings > 0 and not onLift and self.gears[self.client_gearIdx].power > 0 then + self.effect:start() + elseif self.effect:isPlaying() and ( #bearings == 0 or onLift or self.gears[self.client_gearIdx].power == 0 ) then + self.effect:setParameter( "load", 0.5 ) + self.effect:setParameter( "rpm", 0 ) + self.effect:stop() + end + else + if self.effect:isPlaying() and ( #bearings == 0 or onLift or active == false or self.gears[self.client_gearIdx].power == 0 ) then + self.effect:setParameter( "load", 0.5 ) + self.effect:setParameter( "rpm", 0 ) + self.effect:stop() + elseif self.effect:isPlaying() == false and #bearings > 0 and not onLift and active == true and self.gears[self.client_gearIdx].power > 0 then + self.effect:start() + end + end + + if self.effect:isPlaying() then + self.effect:setParameter( "rpm", rpm ) + self.effect:setParameter( "load", engineLoad * 0.5 + 0.5 ) + end +end + +function GasEngine.sv_n_tryUpgrade( self, player ) + + local level = EngineLevels[tostring( self.shape:getShapeUuid() )] + if level and level.upgrade then + local function fnUpgrade() + local nextLevel = EngineLevels[level.upgrade] + assert( nextLevel ) + self.gears = nextLevel.gears + self.network:sendToClients( "cl_n_onUpgrade", level.upgrade ) + + if nextLevel.fn then + nextLevel.fn( self ) + end + + self.shape:replaceShape( sm.uuid.new( level.upgrade ) ) + end + + if sm.game.getEnableUpgrade() then + local inventory = player:getInventory() + + if sm.container.totalQuantity( inventory, obj_consumable_component ) >= level.cost then + + if sm.container.beginTransaction() then + sm.container.spend( inventory, obj_consumable_component, level.cost, true ) + + if sm.container.endTransaction() then + fnUpgrade() + end + end + else + print( "Cannot afford upgrade" ) + end + end + else + print( "Can't be upgraded" ) + end + +end + +function GasEngine.cl_n_onUpgrade( self, upgrade ) + local level = EngineLevels[upgrade] + self.gears = level.gears + self.pointsPerFuel = level.pointsPerFuel + + if self.gui and self.gui:isActive() then + self.gui:setIconImage( "Icon", sm.uuid.new( upgrade ) ) + + if sm.game.getEnableUpgrade() and level.cost then + local inventory = sm.localPlayer.getPlayer():getInventory() + local availableKits = sm.container.totalQuantity( inventory, obj_consumable_component ) + local upgradeData = { cost = level.cost, available = availableKits } + self.gui:setData( "Upgrade", upgradeData ) + else + self.gui:setVisible( "Upgrade", false ) + end + + self.gui:setText( "SubTitle", level.title ) + self.gui:setSliderRangeLimit( "Setting", level.gearCount ) + if level.upgrade then + local nextLevel = EngineLevels[ level.upgrade ] + self.gui:setData( "UpgradeInfo", { Gears = nextLevel.gearCount - level.gearCount, Bearings = nextLevel.bearingCount - level.bearingCount, Efficiency = 1 } ) + self.gui:setIconImage( "UpgradeIcon", sm.uuid.new( level.upgrade ) ) + else + self.gui:setVisible( "UpgradeIcon", false ) + self.gui:setData( "UpgradeInfo", nil ) + end + end + + if self.effect then + --self.effect:destroy() + end + self.effect = sm.effect.createEffect( level.effect, self.interactable ) + sm.effect.playHostedEffect( "Part - Upgrade", self.interactable ) +end \ No newline at end of file diff --git a/Scripts/interactable/Locomotion/ModThruster.lua b/Scripts/interactable/Locomotion/ModThruster.lua new file mode 100644 index 0000000..fd1099c --- /dev/null +++ b/Scripts/interactable/Locomotion/ModThruster.lua @@ -0,0 +1,319 @@ +dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") + +ModThruster = class() +ModThruster.maxParentCount = 3 +ModThruster.maxChildCount = 0 +ModThruster.connectionInput = sm.interactable.connectionType.logic + sm.interactable.connectionType.power + sm.interactable.connectionType.gasoline +ModThruster.connectionOutput = sm.interactable.connectionType.none +ModThruster.colorNormal = sm.color.new(0x29CCCDff) +ModThruster.colorHighlight = sm.color.new(0x36F3F7ff) +ModThruster.poseWeightCount = 3 + + +local PicoThrusterGears = { + { averageForce = 800 }, + { averageForce = 1250 }, + { averageForce = 1500 }, + { averageForce = 2000 }, + { averageForce = 3000 }, + { averageForce = 4000 }, + { averageForce = 5000 }, + { averageForce = 7000 }, + { averageForce = 9000 }, + { averageForce = 11000 }, + { averageForce = 15000 }, + { averageForce = 20000 }, + { averageForce = 25000 } +} + +local OneByOneMicroThruster = { + { averageForce = 2222.22 }, + { averageForce = 3333.33 }, + { averageForce = 5000 }, + { averageForce = 7500 }, + { averageForce = 11250 }, + { averageForce = 16875 }, + { averageForce = 25312.5 }, + { averageForce = 37968.5 }, + { averageForce = 56953.25 }, + { averageForce = 85429.875 }, + { averageForce = 128144.31 }, + { averageForce = 192216.97 }, + { averageForce = 288325.96 } +} + +local thruster_uuid_data = { + ["9235b582-fc25-48a8-a807-68d98755d077"] = { + gears = PicoThrusterGears, + gear_count = #PicoThrusterGears, + effect_offset = sm.vec3.new(0, 0, -0.57) + }, + ["a07a3673-a446-44a3-b16d-abb732c7a525"] = { + gears = OneByOneMicroThruster, + gear_count = #OneByOneMicroThruster, + effect_offset = sm.vec3.new(0, 0, -0.3) + } +} + +function ModThruster:client_onCreate() + local cur_data = thruster_uuid_data[tostring(self.shape.uuid)] + self.gears = cur_data.gears + self.gear_count = cur_data.gear_count + + self.thrust_effect = sm.effect.createEffect("Thruster - Level 1", self.interactable) + self.thrust_effect:setOffsetPosition(cur_data.effect_offset) + + self.cl_thruster_active = false + self.cl_cur_gear = 0 + self.cl_time_val = 0 + self.cl_time_val2 = 0 +end + +function ModThruster:client_onDestroy() + if self.thrust_effect:isPlaying() then + self.thrust_effect:stopImmediate() + end + + if self.gui then + self.gui:close() + self.gui:destroy() + self.gui = nil + end + + self.thrust_effect:destroy() +end + +function ModThruster:client_onClientDataUpdate(params) + local is_active = params[2] + self.cl_thruster_active = is_active + self.cl_cur_gear = params[1] + + local cur_weight = self.cl_cur_gear / (self.gear_count - 1) + self.interactable:setPoseWeight(2, cur_weight) + + local th_effect = self.thrust_effect + + if is_active then + if not th_effect:isPlaying() then + th_effect:start() + end + else + if th_effect:isPlaying() then + th_effect:stop() + end + end +end + +function ModThruster:client_onFixedUpdate() + if self.cl_thruster_active then + local vel_length = sm.util.clamp(self.shape.velocity:length2() / 25, 0, 50) + self.thrust_effect:setParameter("velocity", vel_length) + + self.cl_time_val = self.cl_time_val + 0.2 + self.cl_time_val2 = self.cl_time_val2 + 0.8 + + local light_noise = sm.noise.simplexNoise1d(self.cl_time_val) * 0.5 + self.thrust_effect:setParameter("intensity", 2 + light_noise) + + local thruster_noise = math.abs(math.sin(self.cl_time_val2)) * 0.4 + self.interactable:setPoseWeight(1, thruster_noise) + else + self.interactable:setPoseWeight(1, 0) + end +end + +function ModThruster:client_onSliderChange(widget, value) + self.cl_cur_gear = value + self.network:sendToServer("server_setGear", value) +end + +function ModThruster:client_onGuiClose() + self.gui:destroy() + self.gui = nil +end + +function ModThruster:client_onInteract(character, state) + if state then + local s_gui = sm.gui.createEngineGui() + + s_gui:setText("Name", "#{CONTROLLER_THRUSTER_TITLE}") + s_gui:setText("Interaction", "#{CONTROLLER_THRUSTER_INSTRUCTION}") + s_gui:setSliderCallback("Setting", "client_onSliderChange") + s_gui:setOnCloseCallback("client_onGuiClose") + s_gui:setSliderData("Setting", self.gear_count, self.cl_cur_gear) + s_gui:setIconImage("Icon", self.shape:getShapeUuid()) + s_gui:setVisible("SubTitle", false) + + local fuelContainer = self.interactable:getContainer(0) + if fuelContainer then + s_gui:setContainer("Fuel", fuelContainer) + end + + local externalFuelContainer, _, _ = self:getInputs() + if externalFuelContainer then + s_gui:setVisible("FuelContainer", true) + end + + if not sm.game.getEnableFuelConsumption() then + s_gui:setVisible("BackgroundGas", false) + s_gui:setVisible("FuelGrid", false) + end + + s_gui:open() + self.gui = s_gui + end +end + +function ModThruster:server_onCreate() + self.sv_thruster_active = false + + --load the thruster data + self.saved = self.storage:load() + if self.saved == nil then + self.saved = {} + end + if self.saved.gearIdx == nil then + local cur_data = thruster_uuid_data[tostring(self.shape.uuid)] + + self.saved.gearIdx = math.floor(cur_data.gear_count / 2) + end + if self.saved.fuelPoints == nil then + self.saved.fuelPoints = 0 + end + + self.sv_fuel_points = self.saved.fuelPoints + self:server_setGear(self.saved.gearIdx) + + --create the container or reuse the saved one + local s_container = self.interactable:getContainer(0) + if not s_container then + s_container = self.interactable:addContainer(0, 1, 20) + end + + s_container:setFilters({ obj_consumable_gas }) +end + +function ModThruster:server_setGear(gear) + self.saved.gearIdx = gear + self.sv_data_dirty = true + self.sv_storage_dirty = true +end + +function ModThruster:client_getAvailableParentConnectionCount(connectionType) + if bit.band( connectionType, sm.interactable.connectionType.logic ) == sm.interactable.connectionType.logic then + return 1 - #self.interactable:getParents(sm.interactable.connectionType.logic) + end + + if bit.band( connectionType, sm.interactable.connectionType.power ) == sm.interactable.connectionType.power then + return 1 - #self.interactable:getParents(sm.interactable.connectionType.power) + end + + if bit.band( connectionType, sm.interactable.connectionType.gasoline ) == sm.interactable.connectionType.gasoline then + return 1 - #self.interactable:getParents(sm.interactable.connectionType.gasoline) + end + + return 0 +end + +local s_connection_type = sm.interactable.connectionType +function ModThruster:getInputs() + local s_inter = self.interactable + local l_container_inter = s_inter:getParents(s_connection_type.gasoline)[1] + local l_logic = s_inter:getParents(s_connection_type.logic)[1] + local l_driver_seat = s_inter:getParents(s_connection_type.power)[1] + + local l_container = nil + if l_container_inter then + l_container = l_container_inter:getContainer(0) + end + + return l_container, l_logic, l_driver_seat +end + +function ModThruster:client_onOutOfGas() + local l_player = sm.localPlayer.getPlayer() + local l_character = l_player:getCharacter() + + if l_character then + if (self.shape.worldPosition - l_character.worldPosition):length2() < 100 then + sm.gui.displayAlertText("#{INFO_OUT_OF_FUEL}") + end + end +end + +function ModThruster:server_updateFuelStatus() + if self.saved.fuelPoints ~= self.sv_fuel_points then + self.saved.fuelPoints = self.sv_fuel_points + self.sv_fuel_save_timer = 1 + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfGas") + end + end +end + +function ModThruster:server_onFixedUpdate(dt) + local l_container, l_logic, l_driver_seat = self:getInputs() + local useCreativeFuel = not sm.game.getEnableFuelConsumption() and l_container == nil + + if not l_container or l_container:isEmpty() then + l_container = self.interactable:getContainer(0) + end + + local l_active = false + if l_driver_seat and l_driver_seat.power > 0 then + l_active = true + elseif l_logic and l_logic.active then + l_active = true + end + + local canSpend = false + if self.sv_fuel_points <= 0 then + canSpend = sm.container.canSpend(l_container, obj_consumable_gas, 1) + end + + local is_valid_active = l_active and (self.sv_fuel_points > 0 or canSpend or useCreativeFuel) + if is_valid_active then + local cur_power = self.gears[self.saved.gearIdx + 1].averageForce + sm.physics.applyImpulse(self.shape, sm.vec3.new(0, 0, 0 - cur_power * dt)) + + if not useCreativeFuel then + local fuel_cost = cur_power * 0.1 + self.sv_fuel_points = self.sv_fuel_points - (fuel_cost * dt) + + if self.sv_fuel_points <= 0 then + sm.container.beginTransaction() + sm.container.spend(l_container, obj_consumable_gas, 1, true) + if sm.container.endTransaction() then + self.sv_fuel_points = 10000 + end + end + end + end + + self:server_updateFuelStatus() + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.sv_storage_dirty = true + end + end + + if self.sv_thruster_active ~= is_valid_active then + self.sv_thruster_active = is_valid_active + self.sv_data_dirty = true + end + + if self.sv_storage_dirty then + self.sv_storage_dirty = false + self.storage:save(self.saved) + end + + if self.sv_data_dirty then + self.sv_data_dirty = false + self.network:setClientData({ self.saved.gearIdx, is_valid_active }) + end +end \ No newline at end of file diff --git a/Scripts/interactable/Locomotion/SmartControl.lua b/Scripts/interactable/Locomotion/SmartControl.lua index 1bd69e8..9c1a11f 100644 --- a/Scripts/interactable/Locomotion/SmartControl.lua +++ b/Scripts/interactable/Locomotion/SmartControl.lua @@ -10,20 +10,31 @@ print("loading SmartControl.lua") SmartControl = class( nil ) SmartControl.maxChildCount = -1 SmartControl.maxParentCount = -1 -SmartControl.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +SmartControl.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.electricity SmartControl.connectionOutput = sm.interactable.connectionType.piston + sm.interactable.connectionType.bearing SmartControl.colorNormal = sm.color.new(0xe54500ff) SmartControl.colorHighlight = sm.color.new(0xff7033ff) SmartControl.poseWeightCount = 1 -function SmartControl.server_onCreate(self) +function SmartControl:server_onCreate() self.last_length = {} + self.delta_length = {} + mp_fuel_initialize(self, obj_consumable_battery, 0.35, sm.interactable.connectionType.electricity) + + local saved_points = self.storage:load() + if saved_points ~= nil then + self.sv_fuel_points = saved_points + end + + self.sv_saved_fuel_points = self.sv_fuel_points end + --smart engine/controller (setangle mode(angle, speed, strength), setspeed mode(speed, strength)) --smart piston/suspension (length, speed , strength -function SmartControl.server_onFixedUpdate(self, dt) - local parents = self.interactable:getParents() +local sc_logic_and_power = bit.bor(sm.interactable.connectionType.logic, sm.interactable.connectionType.power) +function SmartControl:server_onFixedUpdate(dt) + local parents = self.interactable:getParents(sc_logic_and_power) local anglelength = nil local speed = nil @@ -73,9 +84,17 @@ function SmartControl.server_onFixedUpdate(self, dt) if strength then strength = sm.util.clamp(strength, -3.402e+38, 3.402e+38) end if anglelength then anglelength = sm.util.clamp(anglelength, -3.402e+38, 3.402e+38) end if stiffness then stiffness = sm.util.clamp(stiffness, -3.402e+38, 3.402e+38) end - - if logic ~= 0 then + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_spend_fuel = mp_fuel_canConsumeFuel(self, l_container) + + if not can_activate then + speed = 0 + end + + if logic ~= 0 and can_activate then + local fuel_cost = 0 + local angle = (anglelength ~= nil and math.rad(anglelength) or nil) local rotationspeed = (speed ~= nil and math.rad(speed) or math.rad(0))-- speed 0 by default as to not let it rotate bearing when no inputs local rotationstrength = (strength ~= nil and strength or 10000) @@ -88,24 +107,38 @@ function SmartControl.server_onFixedUpdate(self, dt) local angle1 = math.deg(angle)%360 - (math.deg(angle)%360 > 180 and 360 or 0) local angle2 = (math.deg(v.angle)%360 - (math.deg(v.angle)%360 > 180 and 360 or 0))*(v.reversed and 1 or -1) local extraforce = math.abs(((angle1 - angle2)+180)%360-180)/1000*stiffness + sm.joint.setTargetAngle( v, angle*seat, rotationspeed, rotationstrength*(1+ extraforce) - v.angularVelocity*10) -- change 10 to 1-200 depending on how well dampening oscillations works - - end + end + + local rotation_val = math.abs(v.angularVelocity) * rotationstrength + fuel_cost = fuel_cost + (rotation_val * 0.04) end local length = (anglelength ~= nil and anglelength or 0) local pistonspeed = (speed ~= nil and speed or 15)--default to 15 local pistonstrength = (strength ~= nil and strength or 6666) for k, v in pairs(sm.interactable.getPistons(self.interactable )) do + local v_id = v.id + local old_length = self.delta_length[v_id] or 0 + -- delta length for suspension-ish - if not self.last_length[v.id] then self.last_length[v.id] = v.length end - local extraforce = math.abs(length - (v.length-1))*stiffness/100 + if not self.last_length[v_id] then self.last_length[v_id] = v.length end + if self.delta_length[v_id] ~= v.length then self.delta_length[v_id] = v.length end - local maxImpulse = pistonstrength*(1+ extraforce ) - (v.length-self.last_length[v.id])*10 -- change 10 to 1-200 depending on how well dampening oscillations works + local extraforce = math.abs(length - (v.length-1))*stiffness/100 + local maxImpulse = pistonstrength*(1+ extraforce ) - (v.length-self.last_length[v_id])*10 -- change 10 to 1-200 depending on how well dampening oscillations works maxImpulse = sm.util.clamp(maxImpulse, -3.402e+38, 3.402e+38) + local p_speed = math.abs(old_length - v.length) * 0.1 + fuel_cost = fuel_cost + (pistonspeed * pistonstrength) * p_speed + sm.joint.setTargetLength( v, length*seat, pistonspeed, maxImpulse ) end + + if can_spend_fuel then + mp_fuel_consumeFuelPoints(self, l_container, fuel_cost, dt) + end else local rotationspeed = (speed ~= nil and math.rad(speed) or math.rad(90)) -- if no input speed setting set , give it a 90°/s speed as to be able to reset bearing to 0° local rotationstrength = (strength ~= nil and strength or 10000) @@ -136,4 +169,26 @@ function SmartControl.server_onFixedUpdate(self, dt) sm.joint.setTargetLength( v, 0, pistonspeed, maxImpulse ) end end + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then + self.sv_saved_fuel_points = self.sv_fuel_points + self.sv_fuel_save_timer = 1 + + if self.sv_fuel_points < 0 then + self.network:sendToClients("client_onOutOfFuel") + end + end + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.storage:save(self.sv_fuel_points) + end + end end + +function SmartControl:client_onOutOfFuel() + mp_fuel_displayOutOfFuelMessage(self, "#{INFO_OUT_OF_ENERGY}") +end \ No newline at end of file diff --git a/Scripts/interactable/Locomotion/SmartThruster.lua b/Scripts/interactable/Locomotion/SmartThruster.lua index 4c9abca..f3ec9cf 100644 --- a/Scripts/interactable/Locomotion/SmartThruster.lua +++ b/Scripts/interactable/Locomotion/SmartThruster.lua @@ -2,6 +2,7 @@ Copyright (c) 2020 Modpack Team Brent Batch#9261 ]]-- + dofile "../../libs/load_libs.lua" print("loading SmartThruster.lua") @@ -10,7 +11,7 @@ print("loading SmartThruster.lua") SmartThruster = class( nil ) SmartThruster.maxParentCount = -1 SmartThruster.maxChildCount = 0 -SmartThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +SmartThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.gasoline SmartThruster.connectionOutput = sm.interactable.connectionType.none SmartThruster.colorNormal = sm.color.new( 0x009999ff ) SmartThruster.colorHighlight = sm.color.new( 0x11B2B2ff ) @@ -18,7 +19,14 @@ SmartThruster.poseWeightCount = 2 function SmartThruster.server_onCreate( self ) + mp_fuel_initialize(self, obj_consumable_gas, 0.35) + + local saved_data = self.storage:load() + if saved_data ~= nil then + self.sv_fuel_points = saved_data + end + self.sv_saved_fuel_points = self.sv_fuel_points end function SmartThruster.server_onRefresh( self ) @@ -26,16 +34,16 @@ function SmartThruster.server_onRefresh( self ) end - +local st_logic_and_power = bit.bor(sm.interactable.connectionType.power, sm.interactable.connectionType.logic) function SmartThruster.server_onFixedUpdate( self, dt ) - local parents = self.interactable:getParents() + local parents = self.interactable:getParents(st_logic_and_power) local power = #parents>0 and 100 or 0 local hasnumber = false local logicinput = 1 for k,v in pairs(parents) do local typeparent = v:getType() - if v:getType() == "scripted" and tostring(v:getShape():getShapeUuid()) ~= "6f2dd83e-bc0d-43f3-8ba5-d5209eb03d07" then + if typeparent == "scripted" and tostring(v:getShape():getShapeUuid()) ~= "6f2dd83e-bc0d-43f3-8ba5-d5209eb03d07" then -- number if not hasnumber then power = 1 end power = power * v.power @@ -51,16 +59,48 @@ function SmartThruster.server_onFixedUpdate( self, dt ) if math.abs(power) >= 3.3*10^38 then -- inf check if power < 0 then power = -3.3*10^38 else power = 3.3*10^38 end end + + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_consume = mp_fuel_canConsumeFuel(self, l_container) + + if not can_activate then + power = 0 + end mp_updateOutputData(self, power * (logicinput or 1), logicinput > 0) - power = power * logicinput - - if power ~= 0 and math.abs(power) ~= math.huge then + + if can_activate and power ~= 0 and math.abs(power) ~= math.huge then sm.physics.applyImpulse(self.shape, sm.vec3.new(0,0, 0 - power)) + + if can_consume then + mp_fuel_consumeFuelPoints(self, l_container, power, dt) + end + end + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then + self.sv_saved_fuel_points = self.sv_fuel_points + self.sv_fuel_save_timer = 1 + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfFuel") + end + end + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.storage:save(self.sv_fuel_points) + end end end +function SmartThruster:client_onOutOfFuel() + mp_fuel_displayOutOfFuelMessage(self) +end + function SmartThruster.client_onCreate(self) self.shootEffect = sm.effect.createEffect( "Thruster - Level 4", self.interactable ) @@ -97,7 +137,8 @@ function SmartThruster.client_onUpdate(self, dt) -- 1 tick delayed vs server but else if self.shootEffect:isPlaying() then - self.shootEffect:stop() end + self.shootEffect:stop() + end end self.interactable:setPoseWeight(0, poseVal0) diff --git a/Scripts/interactable/Locomotion/WASDThruster.lua b/Scripts/interactable/Locomotion/WASDThruster.lua index 957de20..b5584b0 100644 --- a/Scripts/interactable/Locomotion/WASDThruster.lua +++ b/Scripts/interactable/Locomotion/WASDThruster.lua @@ -9,7 +9,7 @@ print("loading WASDThruster.lua") WASDThruster = class( nil ) WASDThruster.maxParentCount = -1 WASDThruster.maxChildCount = 0 -WASDThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic +WASDThruster.connectionInput = sm.interactable.connectionType.power + sm.interactable.connectionType.logic + sm.interactable.connectionType.gasoline WASDThruster.connectionOutput = sm.interactable.connectionType.none WASDThruster.colorNormal = sm.color.new( 0x009999ff ) WASDThruster.colorHighlight = sm.color.new( 0x11B2B2ff ) @@ -26,11 +26,21 @@ function WASDThruster.server_init( self ) self.power = 0 self.direction = sm.vec3.new(0,0,1) self.smode = 0 + + mp_fuel_initialize(self, obj_consumable_gas, 0.35) local stored = self.storage:load() - if stored and type(stored)=="number" then - self.smode = stored - 1 + if stored then + local stored_type = type(stored) + if stored_type == "number" then + self.smode = stored - 1 + elseif stored_type == "table" then + self.smode = stored[1] - 1 + self.sv_fuel_points = stored[2] + end end + + self.sv_saved_fuel_points = self.sv_fuel_points end function WASDThruster.server_onRefresh( self ) @@ -38,16 +48,56 @@ function WASDThruster.server_onRefresh( self ) end function WASDThruster.server_onFixedUpdate( self, dt ) + local l_container = mp_fuel_getValidFuelContainer(self) + local can_activate, can_consume = mp_fuel_canConsumeFuel(self, l_container) + if self.interactable.power ~= self.power then self.interactable:setPower(self.power) end - if self.power > 0 and math.abs(self.power) ~= math.huge then + + if can_activate and self.power > 0 and math.abs(self.power) ~= math.huge then sm.physics.applyImpulse(self.shape, self.direction*self.power*-1) - --print(self.direction) + + if can_consume then + mp_fuel_consumeFuelPoints(self, l_container, self.power, dt) + end + end + + if self.sv_saved_can_activate ~= can_activate then + self.sv_saved_can_activate = can_activate + self.network:setClientData(can_activate) + end + + if self.sv_saved_fuel_points ~= self.sv_fuel_points then --update fuel status + self.sv_saved_fuel_points = self.sv_fuel_points + self.sv_fuel_save_timer = 1 + + if self.sv_fuel_points <= 0 then + self.network:sendToClients("client_onOutOfFuel") + end + end + + if self.sv_fuel_save_timer ~= nil then + self.sv_fuel_save_timer = self.sv_fuel_save_timer - dt + + if self.sv_fuel_save_timer < 0 then + self.sv_fuel_save_timer = nil + self.storage:save({ self.smode+1, self.sv_fuel_points }) + end end end +function WASDThruster:client_onClientDataUpdate(params) + self.cl_can_activate = params +end + + +function WASDThruster:client_onOutOfFuel() + mp_fuel_displayOutOfFuelMessage(self) +end + + function WASDThruster.client_onCreate(self) self.shootEffect = sm.effect.createEffect( "Thruster - Level 2", self.interactable ) self.shootEffect:setOffsetPosition(sm.vec3.zero()) @@ -59,7 +109,7 @@ function WASDThruster.client_onCreate(self) self.currentVPose = 0.5 self.mode = 0 self.network:sendToServer("server_requestmode") - self.modes = {"wasd", "ws reversed", "only WS", "only AD"} + self.modes = {"WASD", "WS Reversed", "Only WS", "Only AD"} self.interactable:setAnimEnabled( "animY", true ) self.interactable:setAnimEnabled( "animX", true ) @@ -67,38 +117,51 @@ end function WASDThruster.client_onDestroy(self) - self.shootEffect:stop() + self.shootEffect:stopImmediate() end function WASDThruster.client_onInteract(self, character, lookAt) if not lookAt or character:getLockingInteractable() then return end self.network:sendToServer("server_changemode", character:isCrouching()) end + function WASDThruster.server_changemode(self, crouch) self.smode = (self.smode + (crouch and -1 or 1))%4 - self.storage:save(self.smode+1) + self.storage:save({ self.smode+1, self.sv_saved_fuel_points }) self.network:sendToClients("client_mode", {self.smode, true}) end + function WASDThruster.server_requestmode(self) self.network:sendToClients("client_mode", {self.smode}) end + function WASDThruster.client_mode(self, mode) if mode[2] then sm.audio.play("ConnectTool - Rotate", self.shape:getWorldPosition()) end self.mode = mode[1] end + +local default_hypertext = "

%s

" function WASDThruster.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - local _crawlKey = sm.gui.getKeyBinding("Crawl") - sm.gui.setInteractionText("Press", _useKey, " / ", _crawlKey.." + ".._useKey, "to change mode") - sm.gui.setInteractionText( "current mode: ".. self.modes[self.mode+1]) + local use_key = sm.gui.getKeyBinding("Use") + local crawl_key = sm.gui.getKeyBinding("Crawl") + + local use_hyper = default_hypertext:format(use_key) + local use_and_crawl_hyper = default_hypertext:format(crawl_key.." + "..use_key) + + sm.gui.setInteractionText("Press", use_hyper, "or", use_and_crawl_hyper, "to change mode") + + local cur_mode_hyper = default_hypertext:format("Mode: "..self.modes[self.mode+1]) + sm.gui.setInteractionText("", cur_mode_hyper) + return true end +local wasdt_logic_and_power = bit.bor(sm.interactable.connectionType.logic, sm.interactable.connectionType.power) function WASDThruster.client_onFixedUpdate(self, dt) - local parents = self.interactable:getParents() + local parents = self.interactable:getParents(wasdt_logic_and_power) local power = #parents>0 and 100 or 0 local hasnumber = false local logicinput = 1 @@ -194,8 +257,17 @@ function WASDThruster.client_onFixedUpdate(self, dt) if ws or ad then self.currentVPose = 0.5 end -- -1 to 1 => 0 to 1 if ad then self.currentHPose = (ad+1)/2 end -- -1 to 1 => 0 to 1 end - self.power = power * logicinput * canfire - if math.abs(self.power) == math.huge or self.power ~= self.power then self.power = 0 end + + --check if the thruster is allowed to have any power + if self.cl_can_activate then + self.power = power * logicinput * canfire + else + self.power = 0 + end + + if math.abs(self.power) == math.huge or self.power ~= self.power then + self.power = 0 + end self.interactable:setUvFrameIndex(self.mode) @@ -213,12 +285,15 @@ function WASDThruster.client_onFixedUpdate(self, dt) local worldRot = sm.vec3.getRotation( getLocal(self.shape,sm.shape.getUp(self.shape)),self.direction) self.shootEffect:setOffsetRotation(worldRot) --self.shootEffect:setOffsetPosition((-sm.vec3.new(0,0,1.25)+self.direction)*0.36) --old calculations + if self.power > 0 then if not self.shootEffect:isPlaying() then - self.shootEffect:start() end + self.shootEffect:start() + end else if self.shootEffect:isPlaying() then - self.shootEffect:stop() end + self.shootEffect:stop() + end end diff --git a/Scripts/interactable/NumberLogic/AsciiBlock.lua b/Scripts/interactable/NumberLogic/AsciiBlock.lua index 7a14c74..ae3bab8 100644 --- a/Scripts/interactable/NumberLogic/AsciiBlock.lua +++ b/Scripts/interactable/NumberLogic/AsciiBlock.lua @@ -340,11 +340,16 @@ function AsciiBlock.client_onInteract(self, character, lookAt) self.network:sendToServer("server_changemode", character:isCrouching()) end +local default_hypertext = "

%s

" function AsciiBlock.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - local _crawlKey = sm.gui.getKeyBinding("Crawl") - sm.gui.setInteractionText("", _useKey, "to cycle forward") - sm.gui.setInteractionText("", _crawlKey.." + ".._useKey, "to cycle backwards") + local use_key = sm.gui.getKeyBinding("Use") + local crawl_key = sm.gui.getKeyBinding("Crawl") + + local use_hyper = default_hypertext:format(use_key) + local crawl_and_use_hyper = default_hypertext:format(crawl_key.." + "..use_key) + + sm.gui.setInteractionText("Press", use_hyper, "or", crawl_and_use_hyper, "to change") + return true end function AsciiBlock.client_playsound(self, sound) diff --git a/Scripts/interactable/NumberLogic/CounterBlock.lua b/Scripts/interactable/NumberLogic/CounterBlock.lua index ed87a83..802dae3 100644 --- a/Scripts/interactable/NumberLogic/CounterBlock.lua +++ b/Scripts/interactable/NumberLogic/CounterBlock.lua @@ -106,36 +106,142 @@ function CounterBlock.server_onFixedUpdate( self, dt ) mp_updateOutputData(self, self.power, self.power > 0) end +function CounterBlock.server_setNewValue(self, value, caller) + self.power = value + + self.network:sendToClient(caller, "client_playSound", 2) +end + +function CounterBlock.server_receiveValue(self, value, caller) + self.power = self.power + value + + self.network:sendToClient(caller, "client_playSound", 2) +end function CounterBlock.server_reset(self) if self.power > 0 then - self.network:sendToClients("client_resetSound") + self.network:sendToClients("client_playSound", 1) end self.power = 0 end -function CounterBlock.client_resetSound(self) - sm.audio.play("GUI Item drag", self.shape:getWorldPosition()) +local sound_id_table = +{ + [1] = "GUI Item drag", + [2] = "GUI Item released" +} + +function CounterBlock.client_playSound(self, sound_id) + local sound_id_table = sound_id_table[sound_id] + + sm.audio.play(sound_id_table, self.shape:getWorldPosition()) end function CounterBlock.client_onInteract(self, character, lookAt) if not lookAt or character:getLockingInteractable() then return end + self.network:sendToServer("server_reset") end +function CounterBlock.client_onTextChangedCallback(self, widget, text) + local converted_text = tonumber(text) --will be nill if the input is invalid + local is_valid = (converted_text ~= nil) + + self.counter_gui_input = text + + local count_gui = self.counter_gui + count_gui:setVisible("ValueError", not is_valid) + + count_gui:setVisible("IncrementWith", is_valid) + count_gui:setVisible("DecrementWith", is_valid) + count_gui:setVisible("SaveWrittenVal", is_valid) +end + +function CounterBlock.client_onGuiCloseCallback(self) + local count_gui = self.counter_gui + if count_gui and sm.exists(count_gui) then + if count_gui:isActive() then + count_gui:close() + end + + count_gui:destroy() + end + + self.counter_gui_input = nil + self.counter_gui = nil +end + +function CounterBlock.client_gui_updateSavedValueText(self) + self.counter_gui:setText("SavedValue", "Saved Value: #ffff00"..tostring(self.interactable.power).."#ffffff") +end + +function CounterBlock.client_gui_changeSavedValue(self, widget) + local is_decrement = (widget:sub(0, 1) == "D") + + local cur_changer = tonumber(self.counter_gui_input) + if cur_changer ~= nil then + if is_decrement then + cur_changer = -cur_changer + end + + self.network:sendToServer("server_receiveValue", cur_changer) + end +end + +function CounterBlock.client_gui_saveWrittenValue(self) + local cur_value = tonumber(self.counter_gui_input) + if cur_value ~= nil then + self.network:sendToServer("server_setNewValue", cur_value) + end +end + +function CounterBlock.client_onTinker(self, character, lookAt) + if not lookAt or character:getLockingInteractable() then return end + + local count_gui = sm.gui.createGuiFromLayout("$CONTENT_DATA/Gui/Layouts/CounterBlockGui.layout", false, { backgroundAlpha = 0.5 }) + + self.counter_gui_input = tostring(self.interactable.power) + + count_gui:setText("SavedValue", "Saved Value: #ffff00"..tostring(self.interactable.power).."#ffffff") + count_gui:setText("ValueInput", self.counter_gui_input) + + count_gui:setButtonCallback("IncrementWith", "client_gui_changeSavedValue") + count_gui:setButtonCallback("DecrementWith", "client_gui_changeSavedValue") + count_gui:setButtonCallback("SaveWrittenVal", "client_gui_saveWrittenValue") + + count_gui:setTextChangedCallback("ValueInput", "client_onTextChangedCallback") + count_gui:setOnCloseCallback("client_onGuiCloseCallback") + + count_gui:open() + + self.counter_gui = count_gui +end function CounterBlock.client_onCreate(self, dt) self.frameindex = 0 self.lastpower = 0 end +function CounterBlock.client_onDestroy(self) + self:client_onGuiCloseCallback() +end + function CounterBlock.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, "to reset counter") + local use_key = sm.gui.getKeyBinding("Use", true) + local tinker_key = sm.gui.getKeyBinding("Tinker", true) + + sm.gui.setInteractionText("Press", use_key, "to reset counter") + sm.gui.setInteractionText("Press", tinker_key, "to open gui") + return true end function CounterBlock.client_onFixedUpdate(self, dt) + local count_gui = self.counter_gui + if count_gui then + self:client_gui_updateSavedValueText() + end + local power = self.interactable.power if self.powerSkip == power then return end -- more performance (only update uv if power changes) diff --git a/Scripts/interactable/NumberLogic/MathBlock.lua b/Scripts/interactable/NumberLogic/MathBlock.lua index 3cabb1c..6c0915f 100644 --- a/Scripts/interactable/NumberLogic/MathBlock.lua +++ b/Scripts/interactable/NumberLogic/MathBlock.lua @@ -879,12 +879,32 @@ function MathBlock.client_onCreate(self) self.network:sendToServer("sv_senduvtoclient") end +function MathBlock.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + +function MathBlock.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function MathBlock.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/MathBlock.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/MathBlock.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for i = 0, 23 do self.gui:setButtonCallback( "Operation" .. tostring( i ), "cl_onModeButtonClick" ) end + for i = 1, 3 do self.gui:setButtonCallback( "Page" .. tostring( i ), "cl_onPageButtonClick" ) end @@ -972,8 +992,9 @@ function MathBlock.cl_setMode(self, data) end function MathBlock.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, " to select a function") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select a function") + return true end diff --git a/Scripts/interactable/NumberOut/SmartSensor.lua b/Scripts/interactable/NumberOut/SmartSensor.lua index 59c7fdd..fd32edd 100644 --- a/Scripts/interactable/NumberOut/SmartSensor.lua +++ b/Scripts/interactable/NumberOut/SmartSensor.lua @@ -197,12 +197,32 @@ function SmartSensor.client_onCreate(self) self.network:sendToServer("sv_requestMode") end +function SmartSensor.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + +function SmartSensor.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function SmartSensor.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/SmartSensor.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/SmartSensor.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for i = 0, 5 do self.gui:setButtonCallback( "Operation" .. tostring( i ), "cl_onModeButtonClick" ) end + self:cl_drawButtons() self.gui:open() end @@ -227,8 +247,9 @@ function SmartSensor.cl_drawButtons(self) end function SmartSensor.client_canInteract(self, character, lookAt) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, "to change mode") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select a sensor mode") + return true end diff --git a/Scripts/interactable/Orientation/Orienter.lua b/Scripts/interactable/Orientation/Orienter.lua index a1106af..0829f36 100644 --- a/Scripts/interactable/Orientation/Orienter.lua +++ b/Scripts/interactable/Orientation/Orienter.lua @@ -161,6 +161,10 @@ function Orienter.client_onCreate(self) self.network:sendToServer("sv_sendModeToClient") end +function Orienter.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + function Orienter.sv_sendModeToClient(self) local _UvIndex = self.modetable[self.mode].savevalue - 1 self.network:sendToClients("cl_setMode", { uvIndex = _UvIndex, mode = self.mode }) @@ -182,9 +186,24 @@ local _UnitTable = { 'UnitsTotebot', 'UnitsWoc', 'UnitsGlowworm' } +function Orienter.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function Orienter.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/Orienter.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/Orienter.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for _, buttonName in pairs(targetTable) do self.gui:setButtonCallback(buttonName, "cl_onTargetButtonClick") end @@ -367,8 +386,9 @@ function Orienter.sv_changeMode(self, params) end function Orienter.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - sm.gui.setInteractionText("Press", _useKey, " to change the mode") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select an orient mode") + return true end diff --git a/Scripts/interactable/Orientation/XOMeter.lua b/Scripts/interactable/Orientation/XOMeter.lua index 2904d4a..ea29590 100644 --- a/Scripts/interactable/Orientation/XOMeter.lua +++ b/Scripts/interactable/Orientation/XOMeter.lua @@ -340,9 +340,9 @@ end function XOMeter.client_canInteract(self) - local _useKey = sm.gui.getKeyBinding("Use") - local _crawlKey = sm.gui.getKeyBinding("Crawl") - sm.gui.setInteractionText("Press", _useKey, " to change the meter mode") + local use_key = sm.gui.getKeyBinding("Use", true) + sm.gui.setInteractionText("Press", use_key, "to select the meter mode") + return true end @@ -358,6 +358,10 @@ function XOMeter.client_onCreate(self) self.network:sendToServer("server_sendModeToClient") end +function XOMeter.client_onDestroy(self) + self:client_onGuiDestroyCallback() +end + function XOMeter.client_onFixedUpdate(self, dt) local mode = self.modetable[self.mode_client] @@ -439,12 +443,28 @@ function XOMeter.client_onFixedUpdate(self, dt) end end +function XOMeter.client_onGuiDestroyCallback(self) + local s_gui = self.gui + if s_gui and sm.exists(s_gui) then + if s_gui:isActive() then + s_gui:close() + end + + s_gui:destroy() + end + + self.gui = nil +end + function XOMeter.client_onInteract(self, character, lookAt) if lookAt == true then - self.gui = sm.gui.createGuiFromLayout('$MOD_DATA/Gui/Layouts/XOMeter.layout') + self.gui = sm.gui.createGuiFromLayout("$MOD_DATA/Gui/Layouts/XOMeter.layout", false, { backgroundAlpha = 0.5 }) + self.gui:setOnCloseCallback("client_onGuiDestroyCallback") + for i = 0, 10 do self.gui:setButtonCallback( "Operation" .. tostring( i ), "cl_onModeButtonClick" ) end + self:cl_drawButtons() self.gui:open() end diff --git a/Scripts/libs/debugger.lua b/Scripts/libs/debugger.lua index b5f6598..989afc8 100644 --- a/Scripts/libs/debugger.lua +++ b/Scripts/libs/debugger.lua @@ -1,9 +1,7 @@ -if _loadedModpackDebugger then - return -end +if _loadedModpackDebugger then return end _loadedModpackDebugger = true local printO = print function print(...) -- fancy print by TechnologicNick - printO("[" .. sm.game.getCurrentTick() .. "]", sm.isServerMode() and "[Server]" or "[Client]", ...) -end + printO(sm.isServerMode() and "[Server]" or "[Client]", ...) +end \ No newline at end of file diff --git a/Scripts/libs/fuel_consumption_manager.lua b/Scripts/libs/fuel_consumption_manager.lua new file mode 100644 index 0000000..53a0fd1 --- /dev/null +++ b/Scripts/libs/fuel_consumption_manager.lua @@ -0,0 +1,58 @@ +dofile("$SURVIVAL_DATA/Scripts/game/survival_items.lua") --to get the uuids of consumable items + +local _sm_getEnableFuelConsumption = sm.game.getEnableFuelConsumption + +function mp_fuel_initialize(self, fuel_uuid, fuel_multiplier, connection_type) + self.sv_fuel_points = 0 + self.sv_fuel_multiplier = fuel_multiplier + self.sv_fuel_uuid = fuel_uuid + self.sv_fuel_connect_type = connection_type or sm.interactable.connectionType.gasoline +end + +function mp_fuel_consumeFuelPoints(self, container, power, dt) + local abs_power = math.abs(power) * self.sv_fuel_multiplier + self.sv_fuel_points = self.sv_fuel_points - (abs_power * dt) --calculate fuel consumption + + if self.sv_fuel_points <= 0 then + sm.container.beginTransaction() + sm.container.spend(container, self.sv_fuel_uuid, 1, true) + if sm.container.endTransaction() then + self.sv_fuel_points = 10000 + end + end +end + +function mp_fuel_getValidFuelContainer(self) + local parents = self.interactable:getParents(self.sv_fuel_connect_type) + for k, v in pairs(parents) do + local gas_container = v:getContainer() + + if gas_container ~= nil then + return gas_container + end + end + + return nil +end + +function mp_fuel_canConsumeFuel(self, container) + local useCreativeFuel = not _sm_getEnableFuelConsumption() and container == nil + local canSpend = false + if self.sv_fuel_points <= 0 and container then + canSpend = sm.container.canSpend(container, self.sv_fuel_uuid, 1) + end + + local is_valid_active = (self.sv_fuel_points > 0 or canSpend or useCreativeFuel) + return is_valid_active, not useCreativeFuel +end + +function mp_fuel_displayOutOfFuelMessage(self, custom_message) + local l_player = sm.localPlayer.getPlayer() + local l_character = l_player:getCharacter() + + if l_character then + if (self.shape.worldPosition - l_character.worldPosition):length2() < 100 then + sm.gui.displayAlertText(custom_message or "#{INFO_OUT_OF_FUEL}") + end + end +end \ No newline at end of file diff --git a/Scripts/libs/game_improvements/interactable.lua b/Scripts/libs/game_improvements/interactable.lua index 9c890d2..6d5f3a7 100644 --- a/Scripts/libs/game_improvements/interactable.lua +++ b/Scripts/libs/game_improvements/interactable.lua @@ -4,28 +4,30 @@ __InteractableImprovements_Loaded = true -- server: local values = {} -- <