Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // NEOPIXEL BEST PRACTICES for most reliable operation:
- // - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections.
- // - MINIMIZE WIRING LENGTH between microcontroller board and first pixel.
- // - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR.
- // - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS
- // connect GROUND (-) first, then +, then data.
- // - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip,
- // a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED.
- // (Skipping these may work OK on your workbench but can fail in the field)
- #include <Adafruit_NeoPixel.h>
- #ifdef __AVR__
- #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
- #endif
- // Digital IO pin connected to the button. This will be driven with a
- // pull-up resistor so the switch pulls the pin to ground momentarily.
- // On a high -> low transition the button press logic will execute.
- #define SOCKET_PIXELS 6
- #define LINK_PIXELS 2
- #define PIXELS_PIN 1
- #define JEWELLER_BUTTON_PIN 0
- #define CHROME_BUTTON_PIN 2
- #define FUSE_BUTTON_PIN 3
- Adafruit_NeoPixel strip(SOCKET_PIXELS + LINK_PIXELS * (SOCKET_PIXELS - 1), PIXELS_PIN, NEO_GRB + NEO_KHZ800);
- const int maxLinks = SOCKET_PIXELS - 1;
- int buttonPins[] = {JEWELLER_BUTTON_PIN, CHROME_BUTTON_PIN, FUSE_BUTTON_PIN};
- int numSockets = 1;
- bool buttonPinsOldState[] = {HIGH, HIGH, HIGH};
- bool buttonPinsNewState[] = {HIGH, HIGH, HIGH};
- int activeLinks[SOCKET_PIXELS - 1];
- int oldActiveLinks[SOCKET_PIXELS - 1];
- int linkPixelMap[LINK_PIXELS * (SOCKET_PIXELS - 1)] = {};
- int socketPixelMap[SOCKET_PIXELS] = {};
- char pixelMap[SOCKET_PIXELS + LINK_PIXELS * (SOCKET_PIXELS - 1)] = {};
- int pixelCount = strip.numPixels();
- bool fullyLinked = LOW;
- int socketColors[SOCKET_PIXELS];
- int oldSocketColors[SOCKET_PIXELS];
- long fusingTable[6][5] = {
- {100000, 100000, 100000, 100000, 100000},
- {33670, 100000, 100000, 100000, 100000},
- {22377, 66461, 100000, 100000, 100000},
- {17991, 53435, 80401, 100000, 100000},
- {17844, 52997, 79741, 99178, 100000},
- {17826, 52944, 79661, 99079, 99900}
- };
- void setup() {
- // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
- // Any other board, you can remove this part (but no harm leaving it):
- #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
- clock_prescale_set(clock_div_1);
- #endif
- // END of Trinket-specific code.
- strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
- strip.show(); // Turn OFF all pixels ASAP
- strip.setBrightness(100); // Set BRIGHTNESS to about 1/5 (max = 255)
- randomSeed(analogRead(4)); // nothing connected to 5 so read sees noise
- pinMode(JEWELLER_BUTTON_PIN, INPUT_PULLUP);
- pinMode(CHROME_BUTTON_PIN, INPUT_PULLUP);
- pinMode(FUSE_BUTTON_PIN, INPUT_PULLUP);
- //set up mapping to pixels
- int socketPixelMapIndex = 0;
- int linkPixelMapIndex = 0;
- for(int pixelIndex = 0; pixelIndex < pixelCount; pixelIndex++) {
- if((pixelIndex % (LINK_PIXELS + 1)) == 0) {
- socketPixelMap[socketPixelMapIndex] = pixelIndex;
- pixelMap[pixelIndex] = 'S';
- socketPixelMapIndex++;
- } else {
- linkPixelMap[linkPixelMapIndex] = pixelIndex;
- pixelMap[pixelIndex] = 'L';
- linkPixelMapIndex++;
- }
- }
- // Initialization before button presses
- int initSockets = jeweller(0);
- numSockets = min(initSockets, SOCKET_PIXELS); // Jeweller's Orb
- chromatic(numSockets); // Chromatic Orb
- fullyLinked = fusing(numSockets); // Fusing Orb
- }
- void loop() {
- /*numSockets = 6;
- testFusings();
- }/*
- testJewellers();
- }*/
- int buttonActive = checkButtons(); // Get current button state.
- switch(buttonActive) { // Determine function based on button press
- case JEWELLER_BUTTON_PIN:
- if((numSockets != SOCKET_PIXELS) && (fullyLinked == LOW)) {
- numSockets = jeweller(numSockets); // Jeweller's Orb
- chromatic(numSockets); // Chromatic Orb
- fullyLinked = fusing(numSockets); // Fusing Orb
- }
- break;
- case CHROME_BUTTON_PIN:
- chromatic(numSockets); // Chromatic Orb
- break;
- case FUSE_BUTTON_PIN:
- if(fullyLinked == LOW) {
- fullyLinked = fusing(numSockets); // Fusing Orb
- }
- break;
- }
- strip.show(); // Update strip with new contents
- delay(50); // Pause for a moment
- }
- // Get current button state.
- int checkButtons() {
- for(int buttonIndex = 0; buttonIndex < 3; buttonIndex++) { // 'buttonPins' counts from 0 to 2...
- buttonPinsOldState[buttonIndex] = buttonPinsNewState[buttonIndex];
- buttonPinsNewState[buttonIndex] = debounceButton(buttonPins[buttonIndex]);
- // Check if state changed from high to low (button press).
- if((buttonPinsNewState[buttonIndex] == LOW) && (buttonPinsOldState[buttonIndex] == HIGH)) {
- buttonPinsOldState[buttonIndex] = buttonPinsNewState[buttonIndex];
- return buttonPins[buttonIndex];
- }
- }
- return -99;
- }
- // Debounce button press
- bool debounceButton(int buttonPin) {
- bool newState = digitalRead(buttonPin);
- delay(20);
- // Check if button is still low after debounce.
- newState = digitalRead(buttonPin);
- if(newState == LOW) { // Yes, still low
- return LOW;
- } else {
- return HIGH;
- }
- }
- // Randomly set number of sockets based on Chris Wilson's percentages + x/6 chance of rolling x sockets for 20% quality
- int jeweller(int incSockets) {
- long randNumber = random(0,100001);
- if(incSockets == 6) {
- return 6;
- } else if((incSockets != 1) && (((numSockets == 2) && (randNumber < 36900)) || ((numSockets == 3) && (randNumber < 37453)) || ((numSockets == 4) && (randNumber < 30211)) || ((numSockets == 5) && (randNumber < 27027)))) {
- return 1;
- } else if((incSockets != 2) && (((numSockets == 1) && (randNumber < 38710)) || ((numSockets == 3) && (randNumber < 77903)) || ((numSockets == 4) && (randNumber < 62840)) || ((numSockets == 5) && (randNumber < 56216)))) {
- return 2;
- } else if((incSockets != 3) && (((numSockets == 1) && (randNumber < 78853)) || ((numSockets == 2) && (randNumber < 78229)) || ((numSockets == 4) && (randNumber < 96676)) || ((numSockets == 5) && (randNumber < 86486)))) {
- return 3;
- } else if((incSockets != 4) && (((numSockets == 1) && (randNumber < 96057)) || ((numSockets == 2) && (randNumber < 95941)) || ((numSockets == 3) && (randNumber < 95880)) || ((numSockets == 5) && (randNumber < 99459)))) {
- return 4;
- } else if((incSockets != 5) && (((numSockets == 1) && (randNumber < 99283)) || ((numSockets == 2) && (randNumber < 99262)) || ((numSockets == 3) && (randNumber < 99251)) || ((numSockets == 4) && (randNumber < 99396)))) {
- return 5;
- } else {
- return 6;
- }
- }
- // Randomly set colors of sockets
- // Note: Chromatic orbs cannot reroll the same color permutation twice, so the chromatic success chance is always higher than the drop rate.
- // For mono-requirement items, on-color: 0.9 * (R + 10) / (R + 20)
- // For mono-requirement items, off-color: 0.05 + 4.5 / (R + 20)
- // For dual-requirement items, on-color: 0.9 * R1 / (R1 + R2)
- // For dual-requirement items, off-color: 10% flat chance, regardless of requirements
- // Requirements: 170 dex
- void chromatic(int numSockets) {
- copy(socketColors, oldSocketColors, SOCKET_PIXELS);
- for(int socketIndex = 0; socketIndex < numSockets; socketIndex++) {
- long randNumber = random(0,100001);
- if(randNumber < 85263) {
- strip.setPixelColor(socketPixelMap[socketIndex], 0, 255, 0);
- socketColors[socketIndex] = 2;
- } else if(randNumber < 92631) {
- strip.setPixelColor(socketPixelMap[socketIndex], 0, 0, 255);
- socketColors[socketIndex] = 3;
- } else {
- strip.setPixelColor(socketPixelMap[socketIndex], 255, 0, 0);
- socketColors[socketIndex] = 1;
- }
- }
- if(numSockets < SOCKET_PIXELS) {
- for(int socketIndex = numSockets; socketIndex < SOCKET_PIXELS; socketIndex++) {
- strip.setPixelColor(socketPixelMap[socketIndex], 0, 0, 0);
- socketColors[socketIndex] = 0;
- }
- }
- bool compareColors = memcmp(socketColors, oldSocketColors, sizeof(socketColors));
- if(!(compareColors)) {
- chromatic(numSockets);
- }
- }
- // Randomly set links of sockets
- bool fusing(int remainingSockets) {
- copy(activeLinks, oldActiveLinks, SOCKET_PIXELS - 1);
- int socketIndex = 0;
- while((remainingSockets > 0) && (socketIndex < numSockets)) {
- int linksNum = 0;
- long randNumber = random(0,100001);
- for(int probIndex = remainingSockets - 1; probIndex > 0; probIndex--) {
- long probCheck = fusingTable[remainingSockets - 1][probIndex - 1];
- if(randNumber > probCheck) {
- linksNum = probIndex;
- break;
- }
- }
- switch(linksNum) {
- case 0: // No links
- setLinks(socketIndex, 0);
- socketIndex++;
- remainingSockets--;
- break;
- case 1: // 1 link
- setLinks(socketIndex, 1);
- socketIndex += 2;
- remainingSockets -= 2;
- break;
- case 2:
- setLinks(socketIndex, 2); // 2 links
- socketIndex += 3;
- remainingSockets -= 3;
- break;
- case 3:
- setLinks(socketIndex, 3); // 3 links
- socketIndex += 4;
- remainingSockets -= 4;
- break;
- case 4:
- setLinks(socketIndex, 4); // 4 links
- socketIndex += 5;
- remainingSockets -= 5;
- break;
- case 5: // fully linked!
- setLinks(socketIndex, 5);
- socketIndex += 6;
- remainingSockets -= 6;
- return HIGH;
- break;
- }
- }
- bool compareLinks = memcmp(activeLinks, oldActiveLinks, sizeof(activeLinks));
- if(!(compareLinks) && (numSockets != 1)) {
- fullyLinked = fusing(numSockets);
- } else {
- return LOW;
- }
- }
- // Set pixels on for active links, and off for the inactive link afterward (if not fully linked)
- void setLinks(int startingSocket, int linksNum) {
- int linkIndex;
- for(int pixelIndex = socketPixelMap[startingSocket]; pixelIndex < pixelCount; pixelIndex++) {
- if(pixelMap[pixelIndex] == 'S') {
- linkIndex = pixelIndex / (LINK_PIXELS + 1);
- } else if(pixelMap[pixelIndex] == 'L') {
- if((linksNum > 0) && (linkIndex < (startingSocket + linksNum))) {
- activeLinks[linkIndex] = 1;
- //strip.setPixelColor(pixelIndex, 255, 0, 255); // Set pixel's color (in RAM)
- strip.setPixelColor(pixelIndex, 90, 100, 15); // Set pixel's color (in RAM)
- } else {
- activeLinks[linkIndex] = 0;
- strip.setPixelColor(pixelIndex, 0, 0, 0); // Set pixel's color off (in RAM)
- }
- }
- }
- }
- // Function to copy 'len' elements from 'src' to 'dst'
- void copy(int* src, int* dst, int len) {
- memcpy(dst, src, sizeof(src[0])*len);
- }
Advertisement
Add Comment
Please, Sign In to add comment