diff --git a/data/font.h b/data/font.h index 33cad999c..fe0c08395 100644 --- a/data/font.h +++ b/data/font.h @@ -236,14 +236,14 @@ unsigned char font_data[] = { 0x0A, 0x00, 0x00, 0x01, 0x00, 0x68, 0x00, 0xA2, 0x02, 0x80, 0x0A, 0x00, 0x25, 0x00, 0x44, 0x08, 0x10, 0x01, 0x40, 0x04, 0x00, 0x14, 0x00, 0x10, 0x00, 0x00, 0x0A, 0xF0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0xFA, 0x00, 0x5B, 0x0E, 0x60, 0x90, 0x00, 0x01, 0x04, 0x06, 0xCD, 0xF1, 0x3F, 0xFD, 0x41, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, - 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0xF8, 0xC1, 0x30, 0xAC, 0xC3, 0x3F, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0xFC, 0x01, 0x4C, 0x07, 0x0C, 0x0D, 0x1C, 0x0C, 0xFC, 0x07, 0x0C, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x0C, 0x00, + 0x0C, 0x06, 0xC0, 0x0F, 0x2B, 0xE0, 0xFF, 0xFF, 0xF0, 0xBF, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0x1F, 0xFD, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF0, 0xFF, 0x0B, 0xF9, 0xFF, 0x02, 0xFF, 0x1F, 0x00, + 0x0C, 0x00, 0xC0, 0x0F, 0x00, 0xF0, 0x0B, 0x00, 0xF0, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x2F, 0xFE, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0xFF, 0xFF, 0x57, 0xFF, 0xFF, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xBF, 0xF8, 0xFF, 0x2F, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x28, 0x00, 0x00, 0x88, 0x00, 0x00, 0x08, 0x00, 0xF0, 0xFF, 0x0F, 0xBC, 0xBE, 0x3E, 0xB0, 0xBE, 0x0E, 0xF0, 0xFF, 0x0F, 0xD0, 0xFF, 0x07, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xCC, 0x00, 0x00, 0x30, 0xC0, 0x0C, 0x30, 0x03, 0xCC, 0x00, 0x33, 0xD0, 0x2C, 0x1D, 0xFD, 0x01, 0x00, 0x00, 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, @@ -291,9 +291,9 @@ short font_ptrs[] = { 0x0E48, 0x0E62, 0x0E7C, 0x0E96, 0x0EB0, 0x0ECA, 0x0EE4, 0x0EFE, 0x0F18, 0x0F26, 0x0F3B, 0x0F53, 0x0F6D, 0x0F87, 0x0FA1, 0x0FBB, 0x0FD5, 0x0FF2, 0x100C, 0x1026, 0x1040, 0x105F, 0x1079, 0x1093, - 0x10AD, 0x10BD, 0x10CD, 0x10DD, 0x10ED, 0x10FD, 0x110D, 0x111D, - 0x112D, 0x113D, 0x114D, 0x115D, 0x116D, 0x117D, 0x118D, 0x119D, - 0x11AD, 0x11BD, 0x11CD, 0x11DD, 0x11ED, 0x11FD, 0x120D, 0x121D, + 0x10AD, 0x10BD, 0x10CD, 0x10E2, 0x1101, 0x1120, 0x113F, 0x115E, + 0x117D, 0x118D, 0x119D, 0x11AD, 0x11BD, 0x11CD, 0x11DD, 0x11ED, + 0x11FD, 0x120D, 0x121D, 0x122D, 0x123D, 0x124D, 0x125D, 0x126D, }; #else extern unsigned char font_data[]; diff --git a/data/font2.h b/data/font2.h new file mode 100644 index 000000000..6e3de999b --- /dev/null +++ b/data/font2.h @@ -0,0 +1,293 @@ +unsigned char font_data[] = { + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xC7, 0x31, 0x0C, 0x02, 0x70, 0x04, 0x00, 0x00, + 0x05, 0xCC, 0x74, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x80, 0x19, 0xCC, 0xE0, 0x3F, 0xCC, 0xF0, 0x2F, 0xCC, 0x90, 0x09, 0x00, 0x00, 0x00, + 0x06, 0x30, 0xD0, 0x3F, 0x33, 0xE1, 0x07, 0xF4, 0x12, 0x33, 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x07, 0x2D, 0xCE, 0xCC, 0xE1, 0x1D, 0xC0, 0x03, 0x74, 0x4B, 0x33, 0xB3, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x7D, 0x30, 0x0C, 0x13, 0xD0, 0x32, 0xB3, 0x33, 0x1C, 0x7D, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x4C, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x34, 0x1D, 0x07, 0x03, 0x07, 0x1D, 0x34, 0x00, 0x00, 0x00, + 0x04, 0x07, 0x1D, 0x34, 0x30, 0x34, 0x1D, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x44, 0xD0, 0x1C, 0x64, 0xF0, 0x3F, 0x64, 0xD0, 0x1C, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x02, 0x30, 0xE0, 0x2F, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0D, 0x03, 0x00, + 0x05, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, + 0x06, 0x80, 0x02, 0x0C, 0xA0, 0x00, 0x03, 0x28, 0xC0, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xF8, 0xE0, 0x39, 0x07, 0x33, 0x32, 0x03, 0xB3, 0x38, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x30, 0xF0, 0x60, 0x03, 0x0C, 0x30, 0xC0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFC, 0xB1, 0x34, 0x41, 0x03, 0x0A, 0x2C, 0x70, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFC, 0x71, 0x34, 0x01, 0x03, 0x1E, 0x00, 0x33, 0x34, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xC0, 0x03, 0x37, 0x1C, 0x73, 0x34, 0xBF, 0x03, 0x30, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0x33, 0x00, 0x57, 0xE0, 0x2F, 0x00, 0x13, 0x30, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xF4, 0xD3, 0x00, 0x07, 0xF0, 0x1F, 0x03, 0x33, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0x07, 0x34, 0x80, 0x03, 0x0E, 0x38, 0xD0, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFC, 0xB1, 0x34, 0x03, 0xD3, 0x1F, 0x03, 0x73, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFC, 0xB1, 0x34, 0x03, 0xC3, 0x3F, 0x40, 0x23, 0x30, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x70, 0x04, 0x40, 0x70, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x1C, 0x04, 0x00, 0x0C, 0x0D, 0x03, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xC0, 0xC3, 0x0B, 0x1B, 0xC0, 0x0B, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x0F, 0x90, 0x83, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFD, 0x71, 0x30, 0x81, 0x03, 0x0E, 0x34, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0xF8, 0x0F, 0x1D, 0x30, 0xE7, 0x37, 0x73, 0x1C, 0xE3, 0x2F, 0x07, 0x00, 0xFD, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x74, 0xD0, 0x1D, 0x47, 0x33, 0x30, 0xFF, 0x33, 0x30, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xBF, 0x30, 0x38, 0x43, 0xF3, 0x1F, 0x43, 0x33, 0x34, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xF4, 0xD1, 0x34, 0x03, 0x31, 0x00, 0x03, 0x70, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x7F, 0x30, 0x1D, 0x43, 0x33, 0x30, 0x03, 0x33, 0x34, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0x32, 0x00, 0x03, 0xF0, 0x0B, 0x03, 0x30, 0x10, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0x33, 0x10, 0x03, 0xF0, 0x0B, 0x03, 0x30, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xF4, 0xD1, 0x34, 0x03, 0x30, 0x3E, 0x03, 0x73, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x47, 0x33, 0x30, 0x03, 0xF3, 0x3F, 0x03, 0x33, 0x30, 0x47, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x1D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x00, 0x00, 0x00, + 0x06, 0xD0, 0x01, 0x0C, 0xC0, 0x00, 0x0C, 0xC0, 0x10, 0x0D, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x47, 0xC3, 0x34, 0x70, 0x03, 0xBC, 0x00, 0xB3, 0xC0, 0xB0, 0x70, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x07, 0x30, 0x00, 0x03, 0x30, 0x00, 0x03, 0x30, 0x10, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x03, 0x30, 0x1F, 0x3D, 0x7B, 0x3B, 0xE3, 0x32, 0x83, 0x30, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0xCD, 0x03, 0x73, 0xC3, 0x8C, 0x32, 0xC3, 0xCD, 0xC0, 0x33, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xF4, 0x41, 0xC7, 0x71, 0xD0, 0x0C, 0x30, 0x03, 0xCD, 0xD1, 0xD1, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x7F, 0x30, 0x1D, 0x43, 0x73, 0x34, 0xFF, 0x31, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xF4, 0x41, 0xD3, 0x71, 0xD0, 0x0C, 0x30, 0xC3, 0xCD, 0xD1, 0xD1, 0xDF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0x31, 0x34, 0x03, 0xF3, 0x0F, 0xD7, 0x30, 0x34, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFC, 0xB1, 0x31, 0x07, 0xD0, 0x0F, 0x90, 0x23, 0x34, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0x13, 0x13, 0x30, 0x00, 0x03, 0x30, 0x00, 0x03, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x03, 0xCC, 0x00, 0x33, 0xC0, 0x0C, 0x30, 0x03, 0xCD, 0xD2, 0xD1, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x03, 0x33, 0x30, 0x03, 0xB3, 0x38, 0xCD, 0xC1, 0x0D, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x03, 0x30, 0x43, 0x30, 0xC7, 0x34, 0xCD, 0x1C, 0xED, 0x1E, 0x2C, 0x0E, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x03, 0x4C, 0xC3, 0x81, 0x3B, 0xD0, 0x03, 0xDC, 0x42, 0xC3, 0x31, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x03, 0xB3, 0x38, 0xDC, 0x40, 0x07, 0x30, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0x0F, 0xD0, 0x02, 0x2C, 0xC0, 0x02, 0x2D, 0xC0, 0x06, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x2F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x2F, 0x00, 0x00, 0x00, + 0x05, 0x03, 0x28, 0xC0, 0x00, 0x0A, 0x30, 0x80, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00, 0x00, 0x00, + 0x04, 0x1D, 0x37, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x83, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0x47, 0x30, 0xFC, 0x0C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x07, 0x0C, 0xF0, 0xC7, 0x35, 0xC3, 0x0C, 0xF3, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0xC3, 0x25, 0x03, 0x4C, 0xD2, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x05, 0xD0, 0x00, 0x83, 0x8F, 0x33, 0xC3, 0x1C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0xBF, 0x0C, 0xD0, 0x0B, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x3D, 0x07, 0x03, 0x2F, 0x03, 0x03, 0x07, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xC0, 0xCB, 0x32, 0xC3, 0xF4, 0x03, 0x4C, 0x30, 0x7E, 0x00, 0x00, + 0x05, 0x03, 0x0C, 0xF0, 0xC7, 0x39, 0xC3, 0x0C, 0x73, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x1C, 0x00, 0x0D, 0x0C, 0x0C, 0x1D, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x30, 0x00, 0x34, 0x30, 0x30, 0x30, 0x30, 0x1E, 0x00, + 0x05, 0x03, 0x0C, 0x31, 0xCE, 0x0E, 0x1F, 0xCC, 0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x47, 0x3D, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x9B, 0x71, 0x37, 0x33, 0x33, 0x32, 0x43, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xF0, 0xC7, 0x31, 0xC3, 0x0C, 0x33, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0xC7, 0x31, 0xC3, 0x4C, 0xD3, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xF0, 0xC7, 0x31, 0xC3, 0x4C, 0xF3, 0xC7, 0x00, 0x03, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0xDF, 0x31, 0xC3, 0x4C, 0xD3, 0x0F, 0x30, 0xC0, 0x00, 0x05, + 0x04, 0x00, 0x00, 0x33, 0x1F, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xC0, 0xC7, 0x10, 0x3C, 0x04, 0xF3, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x1C, 0x74, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x70, 0xDC, 0x30, 0xC3, 0x4C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x30, 0xCC, 0x30, 0xD3, 0xDC, 0xC2, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x47, 0x33, 0x32, 0x33, 0x73, 0x37, 0xCD, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x30, 0xCD, 0x32, 0x7D, 0x8C, 0x73, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x30, 0xCC, 0x30, 0xC7, 0x74, 0x43, 0x07, 0x0C, 0x1F, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xF0, 0x4F, 0x2C, 0x2C, 0x2C, 0xF1, 0x0F, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x38, 0x0C, 0x0C, 0x03, 0x0C, 0x0C, 0x38, 0x00, 0x00, 0x00, + 0x02, 0x32, 0x33, 0x33, 0x13, 0x00, + 0x04, 0x0B, 0x0C, 0x0C, 0x30, 0x0C, 0x0C, 0x0B, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x1D, 0x72, 0x37, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x07, 0x00, 0x1F, 0x00, 0x7F, 0x00, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0x1F, 0xFF, 0x7F, 0xFF, 0x1B, 0xBF, 0x01, 0x1B, 0x00, + 0x0C, 0x00, 0x40, 0xFF, 0x00, 0x00, 0xF8, 0xF0, 0x3F, 0xEE, 0x2C, 0x30, 0xCB, 0x0B, 0x30, 0x42, 0xC3, 0x33, 0x00, 0x03, 0x30, 0x00, 0xF3, 0x33, 0x00, 0x03, 0x30, 0x00, 0xFF, 0x3F, 0x00, + 0x0C, 0xC2, 0x00, 0x00, 0xCB, 0x00, 0x00, 0xEE, 0xC0, 0xFF, 0xF8, 0xB0, 0xC0, 0xFF, 0x2C, 0xC0, 0x00, 0x0C, 0xCF, 0x00, 0x0C, 0xC0, 0x00, 0xCC, 0xCF, 0x00, 0x0C, 0xC0, 0x00, 0xFC, 0xFF, + 0x0A, 0x00, 0x00, 0x0D, 0x00, 0x70, 0x00, 0x00, 0xF3, 0xFF, 0xD3, 0x03, 0xE0, 0x3C, 0x3F, 0x38, 0x03, 0xD0, 0x33, 0xFF, 0x38, 0x03, 0xE0, 0xF0, 0xFF, 0x03, + 0x0C, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x8B, 0xF7, 0x0C, 0x13, 0x9F, 0x3B, 0x37, 0x00, 0xC0, 0x23, 0xFF, 0xFF, 0x8B, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0xD0, 0x7F, 0x80, 0x03, 0x2C, 0x0D, 0x00, 0x37, 0x00, 0xC0, 0xF3, 0xFF, 0x3C, 0xFF, 0xCF, 0x03, 0x00, 0xDC, 0x00, 0x70, 0x38, 0xC0, 0x02, 0xFD, 0x07, + 0x0A, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xF0, 0xFF, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0x03, 0xFF, 0x0F, 0xC0, 0x3F, 0x00, 0x00, 0x00, + 0x0A, 0xFF, 0xFF, 0x3F, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0xF0, 0xC0, 0xC3, 0x3A, 0x3C, 0x0B, 0xCE, 0x2B, 0x80, 0x7E, 0x00, 0xD0, 0x03, 0x00, 0xFC, 0xFF, 0xFF, + 0x0A, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0x03, 0x00, 0x00, + 0x0A, 0xD0, 0x7F, 0x80, 0x03, 0x2C, 0x0D, 0x0F, 0x37, 0xF0, 0xC0, 0xF3, 0xFF, 0x3C, 0xFF, 0xCF, 0x03, 0x0F, 0xDC, 0xF0, 0x70, 0x38, 0xC0, 0x02, 0xFD, 0x07, + 0x0A, 0x40, 0x1F, 0x00, 0xAD, 0x07, 0xB0, 0xC5, 0x00, 0x17, 0x0C, 0x70, 0xD0, 0x00, 0x0C, 0x03, 0xBC, 0xEF, 0xB3, 0x11, 0xE0, 0x07, 0x05, 0x3C, 0x52, 0xC8, + 0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xC0, 0x3F, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 0xFC, 0xFF, 0x3F, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xB8, 0xE0, 0x2F, 0xFF, 0xE3, 0x2F, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0xD0, 0x7F, 0x80, 0xFF, 0x2F, 0xFD, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x7F, 0xF8, 0xFF, 0x02, 0xFD, 0x07, + 0x0A, 0x40, 0x01, 0x00, 0x02, 0x00, 0xC8, 0x07, 0x10, 0xC3, 0x00, 0x31, 0x0D, 0x00, 0xFD, 0x01, 0x00, 0x74, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x00, 0x00, + 0x0A, 0x40, 0x05, 0x80, 0xFF, 0x8B, 0x1E, 0xD0, 0x2E, 0x00, 0xF0, 0x00, 0xE0, 0xFF, 0x0B, 0x00, 0x0F, 0x00, 0xB8, 0x03, 0xB0, 0xE2, 0xFF, 0x02, 0x50, 0x01, + 0x08, 0xFF, 0x07, 0x03, 0x1E, 0x03, 0x73, 0x03, 0xEF, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, + 0x0B, 0x00, 0x00, 0x00, 0xE4, 0x2F, 0xE0, 0x1B, 0x0C, 0x1D, 0x00, 0xFF, 0x03, 0xBE, 0xF0, 0xC1, 0x01, 0xAD, 0x34, 0xC0, 0x36, 0x0B, 0x30, 0xDC, 0xE4, 0x07, 0xFD, 0x1B, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x02, 0xA0, 0xAA, 0x00, 0xA8, 0xC2, 0x0F, 0x2A, 0xFF, 0x03, 0xCA, 0x3F, 0x80, 0xFC, 0x0F, 0x20, 0x0F, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0xC0, 0x01, 0x00, 0xC0, 0x07, 0xAA, 0xEA, 0x1F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xAA, 0xEA, 0x1F, 0x00, 0xC0, 0x07, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, + 0x0C, 0x40, 0x03, 0x00, 0xD0, 0x03, 0x00, 0xF4, 0xAB, 0xAA, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF4, 0xAB, 0xAA, 0xD0, 0x03, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xFE, 0xFF, 0xE3, 0xFF, 0x0F, 0xAA, 0x3E, 0x0A, 0xF8, 0x2E, 0xE0, 0xBF, 0x80, 0xFF, 0xAA, 0xFE, 0xFF, 0xE2, 0xFF, 0x02, 0x02, 0x00, 0x00, + 0x09, 0x00, 0x80, 0x04, 0xD0, 0xE2, 0xFF, 0x02, 0x00, 0x00, 0xFF, 0x6F, 0x00, 0x40, 0xE6, 0xAF, 0x50, 0x00, 0x09, 0x00, 0x20, 0x00, 0x64, 0x00, + 0x09, 0xE0, 0x3F, 0x70, 0x60, 0x63, 0xC0, 0xE4, 0x80, 0xC2, 0x03, 0x07, 0x0F, 0x1E, 0x6C, 0xFF, 0x27, 0xFF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00, + 0x09, 0x44, 0x44, 0x00, 0x12, 0x41, 0x88, 0x04, 0x21, 0x21, 0x84, 0x48, 0x20, 0x23, 0xC2, 0xCC, 0x08, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x1D, 0x00, 0x1D, 0x00, 0x78, 0x00, 0xB4, 0x07, 0xF0, 0x2F, 0xC0, 0xFB, 0x00, 0xBE, 0x02, 0xF4, 0x07, 0xFD, 0xFF, 0x01, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x00, 0x19, 0x00, 0xA8, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xF0, 0xDC, 0xCB, 0x03, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xF0, 0xDC, 0xCB, 0x03, 0x00, 0xFF, 0xFF, 0x0F, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xF0, 0xDC, 0xCB, 0x03, 0x00, 0xFF, 0xFF, 0x0F, 0x40, 0x07, 0x00, 0x74, 0x00, 0x40, 0x03, 0x00, 0x00, + 0x09, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xF0, 0xDC, 0xCB, 0x03, 0x00, 0xFF, 0xFF, 0x4F, 0x07, 0x40, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x0F, 0xFF, 0x3F, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0xFF, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x00, 0xBD, 0x02, 0xE8, 0xB3, 0xE0, 0x3C, 0xAC, 0xC3, 0x03, 0x0F, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0xFC, 0xFF, 0xFF, + 0x0B, 0xC0, 0xC8, 0xC0, 0x91, 0x1B, 0xCD, 0x36, 0xE7, 0x00, 0x47, 0x03, 0xA7, 0x80, 0x36, 0xFD, 0xFF, 0xC1, 0x9B, 0xF9, 0xB8, 0xB8, 0xB8, 0xB7, 0x99, 0xF7, 0xFF, 0xFF, 0x0F, + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xF0, 0x03, 0x00, 0xFC, 0x00, 0xC0, 0xFF, 0x00, 0xF0, 0x3F, 0x00, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0xFC, 0xFF, 0xCF, 0xFF, 0xFF, 0x0F, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, 0xCB, 0x30, 0xC3, 0x3F, 0xC7, 0x00, 0x7E, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0x0C, 0x00, 0xC3, 0xFC, 0x33, 0x0C, 0x24, 0xC3, 0xC0, 0x31, 0x0C, 0x06, 0xC3, 0x30, 0x30, 0x0C, 0x00, 0xC3, 0xFF, 0x3F, + 0x0A, 0xFF, 0x3F, 0x30, 0x00, 0x03, 0xC3, 0x30, 0x30, 0x3F, 0xFF, 0xFF, 0x3F, 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0x0C, 0x0C, 0xC3, 0xC0, 0x00, 0x0C, 0xFC, 0xFF, + 0x0A, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xFC, 0x0F, 0xC0, 0xFF, 0x00, 0xFC, 0x0F, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0x00, 0x00, + 0x09, 0xE0, 0x2F, 0xF0, 0xFF, 0xE3, 0xB8, 0xEC, 0x9B, 0xF9, 0xBF, 0xF8, 0xBF, 0x99, 0xEF, 0xB8, 0x2C, 0xFF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00, + 0x04, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x03, 0x87, 0x87, 0xC3, 0x30, 0x0C, 0xE3, 0xDE, 0x01, + 0x03, 0x74, 0xBB, 0x0C, 0xC3, 0x30, 0x2C, 0x2D, 0x0D, + 0x05, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F, + 0x05, 0x00, 0x00, 0xD0, 0xC7, 0x34, 0xC3, 0x0C, 0x73, 0x4C, 0x1F, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x39, 0xC0, 0x00, 0x43, 0x2F, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0x87, 0x30, 0x60, 0x60, 0x60, 0xC0, 0x3F, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0x87, 0x30, 0xB8, 0x00, 0x23, 0x4C, 0x1F, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0E, 0x36, 0xC6, 0xFC, 0x03, 0x0C, 0x30, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xF0, 0xCB, 0x00, 0x7F, 0x40, 0x13, 0x8C, 0x1F, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0xCB, 0x10, 0x2F, 0x4C, 0x33, 0x4C, 0x1F, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xF0, 0x0F, 0x30, 0x60, 0x60, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0x7D, 0x4C, 0x33, 0x4C, 0x1F, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0xC6, 0xE0, 0x03, 0x8C, 0x1F, 0x00, 0x00, 0x00, + 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x03, 0xC0, 0xF0, 0x3C, 0xCF, 0xF3, 0x3C, 0x03, 0x00, + 0x03, 0x00, 0xCC, 0xF3, 0x3C, 0xCF, 0xF3, 0x30, 0x00, + 0x05, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x30, 0xC0, 0x0F, 0x30, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xD0, 0x7F, 0x40, 0xFF, 0x1F, 0xFC, 0xFF, 0x43, 0xFF, 0x1F, 0x40, 0x15, 0x00, 0x00, 0x00, + 0x0A, 0xE4, 0x06, 0x90, 0x91, 0x01, 0x06, 0x24, 0x30, 0x90, 0x1B, 0x46, 0x6E, 0x96, 0xB9, 0x91, 0xE4, 0x06, 0x0C, 0x18, 0x90, 0x40, 0x46, 0x06, 0x90, 0x1B, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x02, 0xC2, 0xAB, 0xAA, 0x3E, 0x20, 0xE0, 0xAB, 0xAA, 0x3E, 0x02, 0xC2, 0xFF, 0xFF, 0x0F, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x08, 0x02, 0xC0, 0x30, 0x00, 0x0C, 0x03, 0xF0, 0xFF, 0x00, 0xFE, 0x0B, 0xD0, 0x7F, 0x00, 0xA4, 0x01, 0x00, 0x0A, 0x00, 0xA0, 0x00, + 0x0A, 0x00, 0x80, 0x00, 0x81, 0x24, 0x10, 0x85, 0x00, 0x20, 0x66, 0x40, 0x15, 0x45, 0x62, 0x90, 0x4D, 0xD0, 0xF1, 0x23, 0x01, 0xFD, 0x41, 0x41, 0x07, 0x00, + 0x0A, 0x00, 0x05, 0x00, 0xA0, 0x00, 0x40, 0x1F, 0x00, 0xF8, 0x02, 0xD0, 0x7F, 0x00, 0xFE, 0x0B, 0xF0, 0xEF, 0x00, 0xFF, 0x0D, 0xD0, 0x77, 0x00, 0xF4, 0x01, + 0x0A, 0x00, 0x20, 0x00, 0x00, 0x3C, 0x00, 0xD4, 0x01, 0xD0, 0x06, 0x40, 0x7F, 0x00, 0xFD, 0x01, 0xF4, 0x07, 0xD0, 0x1F, 0x00, 0x7F, 0x00, 0xD0, 0x01, 0x00, + 0x0A, 0x40, 0x15, 0x00, 0xFE, 0x0B, 0x88, 0x2F, 0x52, 0xF0, 0x50, 0x01, 0x0A, 0xD4, 0xAF, 0x7F, 0xFD, 0xF5, 0xC7, 0x0B, 0x3E, 0x70, 0xD0, 0x00, 0xA8, 0x02, + 0x0A, 0x80, 0x2F, 0x80, 0x5F, 0x2F, 0x0C, 0x00, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0x01, 0x34, 0x34, 0xC0, 0x01, 0x07, 0x0D, 0xD0, 0x75, 0x00, 0xF4, 0x01, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xF4, 0x01, 0xC0, 0x3F, 0x00, 0xF0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xE0, 0xEF, 0x00, 0xBB, 0x0B, 0xA0, 0xAA, 0x00, 0xAA, 0x0A, 0x80, 0x19, 0x00, 0x64, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x2D, 0x80, 0xE7, 0x0B, 0xBE, 0xF8, 0xFA, 0x02, 0xFE, 0x0B, 0x80, 0x2F, 0x00, 0x50, 0x00, + 0x0A, 0x00, 0x05, 0x00, 0xF8, 0x02, 0xE0, 0xBF, 0x80, 0xAF, 0x2F, 0xBE, 0xE0, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x05, 0x00, 0xA0, 0x00, 0x40, 0x1F, 0x50, 0xFE, 0x5B, 0xFD, 0xFF, 0x47, 0xFF, 0x1F, 0xE0, 0xBF, 0x00, 0xFE, 0x0B, 0xF0, 0xF5, 0x40, 0x01, 0x14, + 0x0A, 0x40, 0x1A, 0x00, 0x09, 0x06, 0x20, 0x80, 0x00, 0x02, 0x08, 0xFC, 0xFF, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0xFF, 0x3F, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0A, 0xF0, 0xFF, 0x00, 0xAA, 0x0A, 0xF0, 0xFF, 0x00, 0x00, 0x00, + 0x09, 0xE0, 0x2F, 0xF0, 0xFF, 0xE3, 0xFF, 0xED, 0xFF, 0xE1, 0xDF, 0xE1, 0x2F, 0xE1, 0xEF, 0xE2, 0x2F, 0xEF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00, + 0x0A, 0xC0, 0x31, 0x00, 0x30, 0x01, 0x40, 0x34, 0x00, 0xCC, 0x00, 0x00, 0x0A, 0x00, 0xF8, 0x02, 0xE0, 0xBF, 0x80, 0xFF, 0x2F, 0xFE, 0xFF, 0xFB, 0xFF, 0xFF, + 0x0A, 0x00, 0x00, 0x80, 0xFF, 0x2F, 0xFC, 0xFF, 0xC3, 0x07, 0x3D, 0x3C, 0xC0, 0xC3, 0x03, 0x3C, 0x7C, 0xD0, 0xC3, 0xFF, 0x3F, 0xF8, 0xFF, 0x02, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0xC0, 0xF3, 0x3C, 0x3C, 0xCF, 0x03, 0x00, 0x00, + 0x0A, 0xB9, 0x91, 0xE3, 0x46, 0x2E, 0x1B, 0xB9, 0x61, 0xE4, 0x06, 0x91, 0x1B, 0x41, 0x6E, 0x24, 0xB9, 0x91, 0xE3, 0x46, 0x2E, 0x1B, 0xB9, 0x01, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x0C, 0xC0, 0x23, 0x00, 0x80, 0x08, 0x00, 0x20, 0x0F, 0xC0, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0xE0, 0x2F, 0xC0, 0x01, 0x0D, 0x06, 0x40, 0x32, 0x00, 0x30, 0x03, 0x00, 0x33, 0x00, 0x30, 0x06, 0x40, 0xC2, 0x01, 0x0D, 0xE0, 0x2F, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x23, 0x80, 0x32, 0x0A, 0x0D, 0xC3, 0xD1, 0x10, 0x1C, 0x0D, 0xC0, 0x81, 0x02, 0x0A, 0xE0, 0x2F, 0x00, 0x54, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xB0, 0xE0, 0x00, 0x03, 0x0C, 0x30, 0xC0, 0x00, 0x0B, 0x0E, 0xC0, 0x3F, 0x00, 0xAC, 0x03, 0xC0, 0x3A, 0x00, 0xAC, 0x03, + 0x05, 0x6F, 0xBC, 0xF1, 0xC6, 0x1B, 0x6F, 0xBC, 0xF1, 0xC6, 0x1B, 0x6F, 0x00, 0x00, + 0x08, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0x00, 0x00, + 0x09, 0x00, 0xE4, 0x03, 0x90, 0x0F, 0x40, 0x3E, 0x00, 0xF9, 0x00, 0xE4, 0x03, 0x90, 0x0F, 0x40, 0x3E, 0x00, 0xF9, 0x00, 0xE4, 0x03, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x08, 0x82, 0xE0, 0xBA, 0x2E, 0x08, 0x82, 0x80, 0x20, 0x08, 0xAE, 0xEB, 0x82, 0x20, 0x08, 0x08, 0x82, 0xE0, 0xBA, 0x2E, 0x08, 0x82, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x30, 0x00, 0x00, 0x03, 0x30, 0xFC, 0x00, 0x43, 0x07, 0xFC, 0x20, 0x40, 0x07, 0x30, 0x20, 0x00, 0x03, 0x00, 0xFC, 0x00, 0x40, 0x07, 0x00, 0x20, + 0x0A, 0x00, 0x43, 0xC0, 0x20, 0x1D, 0x20, 0x61, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x24, 0xB4, 0xF1, 0x01, 0xFE, 0x0F, 0xD0, 0x0F, 0x00, 0xFC, + 0x0A, 0x00, 0x00, 0x00, 0x54, 0x00, 0x90, 0x1A, 0x40, 0xFE, 0x06, 0xE4, 0x6F, 0x40, 0xFE, 0x06, 0x90, 0x1A, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x88, 0x88, 0x88, 0x55, 0x55, 0x55, 0xFF, 0x00, 0x54, 0x55, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0xA5, 0x6B, 0x01, 0x64, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xFF, 0x86, 0xC0, 0x00, 0x2C, 0x40, 0xFE, 0x0B, 0xE4, 0xBF, 0x0C, 0xC0, 0xF2, 0x6F, 0x08, 0x0C, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x05, 0x00, 0xF4, 0x01, 0xC0, 0x30, 0x00, 0x0D, 0x07, 0xF0, 0xF0, 0x40, 0x5F, 0x1F, 0xFC, 0xFA, 0xD3, 0xFF, 0x7F, 0xFF, 0xF0, 0xDF, 0xFF, 0x7F, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1E, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x60, 0x00, 0x24, 0x98, 0x01, 0x80, 0x42, 0x06, 0x00, 0x00, 0x19, 0x00, 0x00, 0x04, + 0x0A, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x5C, 0x0D, 0xC0, 0xC1, 0x00, 0x1C, 0x0C, 0x40, 0xFF, 0x01, 0x00, 0x74, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x01, 0x00, 0x68, 0x00, 0xA2, 0x02, 0x80, 0x0A, 0x00, 0x25, 0x00, 0x44, 0x08, 0x10, 0x01, 0x40, 0x04, 0x00, 0x14, 0x00, 0x10, 0x00, 0x00, + 0x0A, 0xF0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0xFA, 0x00, 0x5B, 0x0E, 0x60, 0x90, 0x00, 0x01, 0x04, + 0x06, 0xCD, 0xF1, 0x3F, 0xFD, 0x41, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xF8, 0xC1, 0x30, 0xAC, 0xC3, 0x3F, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0xFC, 0x01, 0x4C, 0x07, 0x0C, 0x0D, 0x1C, 0x0C, 0xFC, 0x07, 0x0C, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x0C, 0x00, + 0x0C, 0x06, 0xC0, 0x0F, 0x2B, 0xE0, 0xFF, 0xFF, 0xF0, 0xBF, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0x1F, 0xFD, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF0, 0xFF, 0x0B, 0xF9, 0xFF, 0x02, 0xFF, 0x1F, 0x00, + 0x0C, 0x00, 0xC0, 0x0F, 0x00, 0xF0, 0x0B, 0x00, 0xF0, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x2F, 0xFE, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0xFF, 0xFF, 0x57, 0xFF, 0xFF, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xBF, 0xF8, 0xFF, 0x2F, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x28, 0x00, 0x00, 0x88, 0x00, 0x00, 0x08, 0x00, 0xF0, 0xFF, 0x0F, 0xBC, 0xBE, 0x3E, 0xB0, 0xBE, 0x0E, 0xF0, 0xFF, 0x0F, 0xD0, 0xFF, 0x07, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xCC, 0x00, 0x00, 0x30, 0xC0, 0x0C, 0x30, 0x03, 0xCC, 0x00, 0x33, 0xD0, 0x2C, 0x1D, 0xFD, 0x01, 0x00, 0x00, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, + 0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07, +}; + +short font_ptrs[] = { + 0x0000, 0x000E, 0x001C, 0x002A, 0x0038, 0x0046, 0x0054, 0x0062, + 0x0070, 0x007E, 0x008C, 0x009A, 0x00A8, 0x00B6, 0x00C4, 0x00D2, + 0x00E0, 0x00EE, 0x00FC, 0x010A, 0x0118, 0x0126, 0x0134, 0x0142, + 0x0150, 0x015E, 0x016C, 0x017A, 0x0188, 0x0196, 0x01A4, 0x01B2, + 0x01C0, 0x01CE, 0x01D7, 0x01E5, 0x01F5, 0x0205, 0x0218, 0x0228, + 0x0231, 0x023C, 0x0247, 0x0257, 0x0267, 0x0272, 0x0280, 0x0289, + 0x0299, 0x02A9, 0x02B7, 0x02C7, 0x02D7, 0x02E7, 0x02F7, 0x0307, + 0x0317, 0x0327, 0x0337, 0x0340, 0x034B, 0x035B, 0x036B, 0x037B, + 0x038B, 0x03A0, 0x03B0, 0x03C0, 0x03D0, 0x03E0, 0x03F0, 0x0400, + 0x0410, 0x0420, 0x042B, 0x043B, 0x044E, 0x045E, 0x0473, 0x0486, + 0x0499, 0x04A9, 0x04BC, 0x04CC, 0x04DC, 0x04EC, 0x04FF, 0x050F, + 0x0524, 0x0537, 0x0547, 0x055A, 0x0565, 0x0573, 0x057E, 0x0589, + 0x0599, 0x05A2, 0x05B0, 0x05BE, 0x05CC, 0x05DA, 0x05E8, 0x05F3, + 0x0601, 0x060F, 0x061A, 0x0625, 0x0633, 0x063E, 0x064E, 0x065C, + 0x066A, 0x0678, 0x0686, 0x0691, 0x069F, 0x06AA, 0x06B8, 0x06C6, + 0x06D6, 0x06E4, 0x06F2, 0x0700, 0x070B, 0x0711, 0x071C, 0x072C, + 0x0737, 0x074C, 0x076B, 0x078A, 0x07A4, 0x07C3, 0x07DD, 0x07F7, + 0x0811, 0x082B, 0x0845, 0x085F, 0x0879, 0x0898, 0x08A8, 0x08C2, + 0x08DC, 0x08F6, 0x0910, 0x0925, 0x0942, 0x095F, 0x097E, 0x099D, + 0x09B5, 0x09CD, 0x09E5, 0x09FD, 0x0A15, 0x0A2D, 0x0A45, 0x0A5D, + 0x0A75, 0x0A8D, 0x0AA5, 0x0ABF, 0x0ADC, 0x0AF9, 0x0B0E, 0x0B28, + 0x0B42, 0x0B5C, 0x0B76, 0x0B8E, 0x0B99, 0x0BA2, 0x0BAB, 0x0BB9, + 0x0BC7, 0x0BD5, 0x0BE3, 0x0BF1, 0x0BFF, 0x0C0D, 0x0C1B, 0x0C29, + 0x0C37, 0x0C45, 0x0C50, 0x0C59, 0x0C62, 0x0C70, 0x0C80, 0x0C90, + 0x0CAA, 0x0CC4, 0x0CDE, 0x0CF8, 0x0D12, 0x0D2C, 0x0D46, 0x0D60, + 0x0D7A, 0x0D94, 0x0DAE, 0x0DC8, 0x0DE2, 0x0DFC, 0x0E16, 0x0E30, + 0x0E48, 0x0E62, 0x0E7C, 0x0E96, 0x0EB0, 0x0ECA, 0x0EE4, 0x0EFE, + 0x0F18, 0x0F26, 0x0F3B, 0x0F53, 0x0F6D, 0x0F87, 0x0FA1, 0x0FBB, + 0x0FD5, 0x0FF2, 0x100C, 0x1026, 0x1040, 0x105F, 0x1079, 0x1093, + 0x10AD, 0x10BD, 0x10CD, 0x10E2, 0x1101, 0x1120, 0x113F, 0x115E, + 0x117D, 0x1190, 0x11A0, 0x11B0, 0x11C0, 0x11D0, 0x11E0, 0x11F0, + 0x1200, 0x1210, 0x1220, 0x1230, 0x1240, 0x1250, 0x1260, 0x1270, +}; diff --git a/font/editor.c b/font/editor.c index cdd748693..8da16dfe5 100644 --- a/font/editor.c +++ b/font/editor.c @@ -385,6 +385,7 @@ int main(int argc, char *argv[]) #endif sdl_blit(0, 0, XRES, YRES, vid_buf, XRES*4); + SDL_Delay(1); } f = fopen("font.bin", "wb"); diff --git a/src/client/Client.h b/src/client/Client.h index 2f3a0b0ed..1d84755d7 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -69,6 +69,8 @@ private: //Auth session User authUser; + int coins; + //Thumbnail retreival int thumbnailCacheNextID; Thumbnail * thumbnailCache[THUMB_CACHE_SIZE]; @@ -185,6 +187,10 @@ public: bool CheckUpdate(void *updateRequest, bool checkSession); void Shutdown(); + void SetCoins(int coins) { this->coins = coins; } + void AddCoins(int coins) { this->coins += coins; } + int GetCoins() { return coins; } + // preferences functions void WritePrefs(); diff --git a/src/graphics/Graphics.cpp b/src/graphics/Graphics.cpp index 69d3ad342..fc058f2ef 100644 --- a/src/graphics/Graphics.cpp +++ b/src/graphics/Graphics.cpp @@ -1083,6 +1083,12 @@ void Graphics::draw_icon(int x, int y, Icon icon, unsigned char alpha, bool inve drawchar(x+1, y+1, 0xD5, 55, 255, 55, alpha); } break; + case IconCoin: + if (invert) + drawchar(x+1, y+1, 0xEA, 50, 50, 0, alpha); + else + drawchar(x+1, y+1, 0xEA, 255, 255, 200, alpha); + break; default: if(invert) drawchar(x, y, 't', 0, 0, 0, alpha); diff --git a/src/graphics/Icons.h b/src/graphics/Icons.h index 8f3dc68d4..9b9f7da2e 100644 --- a/src/graphics/Icons.h +++ b/src/graphics/Icons.h @@ -40,7 +40,8 @@ enum Icon IconPersistant, IconHeat, IconLife, - IconGradient + IconGradient, + IconCoin, }; #endif // ICONS_H diff --git a/src/gui/coin/CardInput.cpp b/src/gui/coin/CardInput.cpp new file mode 100644 index 000000000..2f110438f --- /dev/null +++ b/src/gui/coin/CardInput.cpp @@ -0,0 +1,422 @@ +#include +#include "CardInput.h" +#include "Format.h" +#include "client/Client.h" +#include "graphics/Graphics.h" +#include "gui/dialogues/ConfirmPrompt.h" +#include "gui/dialogues/InformationMessage.h" +#include "gui/dialogues/ErrorMessage.h" +#include "gui/interface/Button.h" +#include "gui/interface/DropDown.h" +#include "gui/interface/Engine.h" +#include "gui/interface/Label.h" +#include "gui/interface/Textbox.h" + +CardInput::CardInput(int chance, int amount): + ui::Window(ui::Point(-1, -1), ui::Point(300, 200)), + purchaseChance(chance), + amount(amount) +{ + class NextAction: public ui::ButtonAction + { + public: + void ActionCallback(ui::Button * sender) + { + ((CardInput*)sender->GetParentWindow())->Next(); + } + }; + next = new ui::Button(ui::Point(250, 175), ui::Point(45, 20), "Next"); + next->SetActionCallback(new NextAction()); + AddComponent(next); + + SetOkayButton(next); + + signature = nullptr; + Step1(); +} + +void CardInput::Next() +{ + if (step == 1) + Step2(); + else if (step == 2) + AttemptPurchase(); +} + +void CardInput::AttemptPurchase() +{ + std::string error; + int num = 0;//rand()%100; + if (num < purchaseChance) + { + bool confirm = ConfirmPrompt::Blocking("Purchase \xEA""owdercoins?", "Clicking 'Confirm' will charge your card and add " + + format::NumberToString(amount) + " \xEA""owdercoins to your account"); + if (confirm) + { + Client::Ref().AddCoins(amount); + CloseActiveWindow(); + SelfDestruct(); + new InformationMessage("Confirmed!", "New balance: " + format::NumberToString(Client::Ref().GetCoins()), false); + //ui::Engine::Ref().ShowWindow(info); + return; + } + return; + } + if (num < 30) + error = "Card did not go through. Please revalidate card information"; + else if (num < 40) + error = "Card expired. Please use a valid card"; + else if (num < 50) + error = "Signature too messy. Please take handwriting classes then retry."; + else if (num < 60) + error = "We cannot process purchases in this country at this time"; + else if (num < 70) + error = "Invalid address. We could not find this address in our systems"; + else if (num < 90) + error = "Card type not supported. Supported card types are: 'L\xF0""F Lirpa The Powder Toy EXTRAVote Co-Branded Credit Card"; + else + error = "Our payment processing systems are currently on fire. Please try again later"; + ErrorMessage::Blocking("Failure buying \xEA""owdercoins", error); + CloseActiveWindow(); + // You have 10 seconds to read this message before it self destructs + SelfDestruct(); +} + +void CardInput::Step1() +{ + ClearComponents(1); + + std::string labelText = "\boInput credit or debit card"; + int labelSize = Graphics::textwidth(labelText.c_str()); + ui::Label *label = new ui::Label(ui::Point(8, 5), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + class CardInputHelper : public ui::TextboxAction + { + CardInput * v; + ui::Component *next; + public: + CardInputHelper(CardInput * v, ui::Component *next) { this->v = v; this->next = next; } + virtual void TextChangedCallback(ui::Textbox * sender) + { + if (sender->GetText().length() == 4) + v->FocusComponent(next); + } + }; + + labelText = "Card Number: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 25), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + ui::Textbox *card1 = new ui::Textbox(ui::Point(labelSize + 15, 25), ui::Point(35, 20)); + card1->SetInputType(ui::Textbox::Number); + card1->SetLimit(4); + AddComponent(card1); + + ui::Textbox *card2 = new ui::Textbox(ui::Point(labelSize + 55, 25), ui::Point(35, 20)); + card2->SetInputType(ui::Textbox::Number); + card2->SetLimit(4); + AddComponent(card2); + + ui::Textbox *card3 = new ui::Textbox(ui::Point(labelSize + 95, 25), ui::Point(35, 20)); + card3->SetInputType(ui::Textbox::Number); + card3->SetLimit(4); + AddComponent(card3); + + ui::Textbox *card4 = new ui::Textbox(ui::Point(labelSize + 135, 25), ui::Point(35, 20)); + card4->SetInputType(ui::Textbox::Number); + card4->SetLimit(3); + AddComponent(card4); + + card1->SetActionCallback(new CardInputHelper(this, card2)); + card2->SetActionCallback(new CardInputHelper(this, card3)); + card3->SetActionCallback(new CardInputHelper(this, card4)); + //card4->SetActionCallback(new CardInputHelper(this, card2)); + textboxChecks.push_back(card1); + textboxChecks.push_back(card2); + textboxChecks.push_back(card3); + textboxChecks.push_back(card4); + + + labelText = "Expiration Date: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 55), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + ui::DropDown *expirationMonth = new ui::DropDown(ui::Point(labelSize + 15, 55), ui::Point(25, 20)); + expirationMonth->SetOptions({ + {"01", 1}, + {"02", 2}, + {"03", 3}, + {"04", 4}, + {"05", 5}, + {"06", 6}, + {"07", 7}, + {"08", 8}, + {"09", 9}, + {"10", 10}, + {"11", 11}, + {"12", 12} + }); + expirationMonth->SetOption(1); + AddComponent(expirationMonth); + + ui::DropDown *expirationYear = new ui::DropDown(ui::Point(labelSize + 45, 55), ui::Point(35, 20)); + for (int i = 0; i < 15; i++) + expirationYear->AddOption({format::NumberToString(2017-i), i+1}); + expirationYear->SetOption(1); + AddComponent(expirationYear); + + labelText = "Security Code: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(180, 55), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + ui::Textbox *securityCode = new ui::Textbox(ui::Point(labelSize + 180, 55), ui::Point(25, 20)); + securityCode->SetInputType(ui::Textbox::Number); + securityCode->SetLimit(3); + AddComponent(securityCode); + textboxChecks.push_back(securityCode); + + + labelText = "Sign Here: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 85), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + signature = new VideoBuffer(250, 50); + class ClearSigAction: public ui::ButtonAction + { + VideoBuffer * signature; + public: + ClearSigAction(VideoBuffer * signature) { this->signature = signature; } + void ActionCallback(ui::Button * sender) + { + pixel *buf = signature->Buffer; + std::fill(&buf[0], &buf[signature->Width*signature->Height], 0); + ((CardInput*)sender->GetParentWindow())->signatureValid = false; + } + }; + + ui::Button *clearSignature = new ui::Button(ui::Point(10, 154), ui::Point(75, 20), "Clear Signature"); + clearSignature->SetActionCallback(new ClearSigAction(signature)); + AddComponent(clearSignature); +} + +void CardInput::Step2() +{ + ClearComponents(2); + + std::string labelText = "\boInput billing address"; + int labelSize = Graphics::textwidth(labelText.c_str()); + ui::Label *label = new ui::Label(ui::Point(8, 5), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + labelText = "Country: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 25), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + //std::vector countryList = {"Afghanistan", "Albania", "Algeria", "Antarctica", "Argentina", "Armenia", "Atlantis", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Belarus", "Belgium", "Bolivia", "Brazil", "Bulgaria", "Cambodia", "Cameroon", "Canada, eh?", "California", "Chad", "Chile", "China", "Colombia", "Democratic People's Republic of Korea", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Estonia", "Ethiopia", "European Union", "Fiji", "Finland", "France", "Georgia", "East Germany", "West Germany", "Ghana", "Greece", "Guatemala", "Guinea", "Haiti", "Honduras", "Hungry", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Islamic State of Iraq and Syria", "Israel", "Italy", "Jamaica", "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kosovo", "Kuwait", "Kyrgyzstan", "Laos", "Latvia", "Lebanon", "Ledhlzigstan", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Longitudinal Guinea", "Luxembourg", "Macedonia (Greek Province)", "Madagascar", "Malaysia", "Malta", "Mexico", "Moldova", "Mongolia", "Montenegro", "Morocco", "Mozambique", "Murrica", "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands", "New York City", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Norway", "Oman", "Pakistan", "Palau", "Palestine", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Qatar", "Romania", "Russia", "Rwanda", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Sierra Leone", "Singapore", "Slopokia", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Dakota", "South Korea", "South Sudan", "Spain", "Sri Lanka", "Sudan", "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Texas", "Tieland", "Turkey", "Ham", "Turkmenistan", "Tuvalu", "Uganda", "Ukraine", "UAE", "United Kingdom (UK)", "Uranus", "Uruguay", "USSR", "Uzbekistan", "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wakanda", "Yemen", "Zambia", "Zimbabwe"}; + std::vector countryList = {"United States of America", "Other"}; + ui::DropDown *countryDropdown = new ui::DropDown(ui::Point(labelSize + 15, 25), ui::Point(150, 20)); + int num = 0; + for (std::string country : countryList) + { + countryDropdown->AddOption(std::pair(country, num)); + num++; + } + countryDropdown->SetOption(0); + AddComponent(countryDropdown); + + labelText = "State: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 50), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + std::vector stateList = {"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"}; + std::sort(&stateList[0], &stateList[stateList.size()], [](std::string a, std::string b) { return a.length() < b.length(); }); + ui::DropDown *stateDropdown = new ui::DropDown(ui::Point(labelSize + 15, 50), ui::Point(70, 20)); + num = 0; + for (std::string state : stateList) + { + stateDropdown->AddOption(std::pair(state, num)); + num++; + } + stateDropdown->SetOption(0); + AddComponent(stateDropdown); + + + labelText = "Street line 1: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 75), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + ui::Textbox * textbox = new ui::Textbox(ui::Point(labelSize + 15, 75), ui::Point(200, 20)); + textbox->SetInputType(ui::Textbox::Number); + textbox->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + AddComponent(textbox); + textboxChecks.push_back(textbox); + + labelText = "Street line 2: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 100), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + textbox = new ui::Textbox(ui::Point(labelSize + 15, 100), ui::Point(200, 20)); + textbox->SetLimit(5); + textbox->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + AddComponent(textbox); + textboxChecks.push_back(textbox); + + + labelText = "City: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 125), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + textbox = new ui::Textbox(ui::Point(labelSize + 15, 125), ui::Point(100, 20)); + textbox->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + AddComponent(textbox); + textboxChecks.push_back(textbox); + + labelText = "Zip Code: "; + labelSize = Graphics::textwidth(labelText.c_str()); + label = new ui::Label(ui::Point(15, 150), ui::Point(labelSize, 16), labelText); + AddComponent(label); + + textbox = new ui::Textbox(ui::Point(labelSize + 15, 150), ui::Point(50, 20)); + textbox->SetInputType(ui::Textbox::Numeric); + textbox->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + AddComponent(textbox); + textboxChecks.push_back(textbox); +} + +void CardInput::ClearComponents(int step) +{ + textboxChecks.clear(); + for (int i = Components.size()-1; i >= 0; i--) + { + if (Components[i] != next) + RemoveComponent(i); + } + this->step = step; +} + +CardInput::~CardInput() +{ + delete signature; +} + +void CardInput::OnDraw() +{ + Graphics * g = GetGraphics(); + + g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); + g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); + + if (step == 1) + { + g->draw_image(signature->Buffer, Position.X+10, Position.Y+105, 250, 50, 255); + g->drawrect(Position.X+10, Position.Y+105, 250, 50, 255, 255, 255, 255); + } +} + +void CardInput::OnTick(float dt) +{ + bool valid = true; + for (auto textbox : textboxChecks) + { + if (textbox->GetText().length() < 3) + valid = false; + } + + if (next) + next->Enabled = valid && (step != 1 || signatureValid); +} + +void CreateLine(int x1, int y1, int x2, int y2, VideoBuffer *signature) +{ + bool reverseXY = abs(y2-y1) > abs(x2-x1); + int x, y, dx, dy, sy; + float e, de; + if (reverseXY) + { + y = x1; + x1 = y1; + y1 = y; + y = x2; + x2 = y2; + y2 = y; + } + if (x1 > x2) + { + y = x1; + x1 = x2; + x2 = y; + y = y1; + y1 = y2; + y2 = y; + } + dx = x2 - x1; + dy = abs(y2 - y1); + e = 0.0f; + if (dx) + de = dy/(float)dx; + else + de = 0.0f; + y = y1; + sy = (y1SetPixel(y, x, 255, 255, 255, 255); + else + signature->SetPixel(x, y, 255, 255, 255, 255); + e += de; + if (e >= 0.5f) + { + y += sy; + if ((y1=y2)) + { + if (reverseXY) + signature->SetPixel(y, x, 255, 255, 255, 255); + else + signature->SetPixel(x, y, 255, 255, 255, 255); + } + e -= 1.0f; + } + } +} + +void CardInput::OnMouseMove(int x, int y, int dx, int dy) +{ + if (step == 1 && x >= Position.X+10 && x < Position.X+260 && y > Position.Y+105 && y < Position.Y+155) + { + if (drawing) + { + // extra accuracy + dx += (int)(((rand()%11)-5)/5); + dy += (int)(((rand()%11)-5)/5); + CreateLine(x - (Position.X+10), y - (Position.Y+105), x - (Position.X+10) - dx, y - (Position.Y+105) - dy, signature); + signatureValid = true; + } + } +} + +void CardInput::OnMouseDown(int x, int y, unsigned button) +{ + drawing = true; +} + +void CardInput::OnMouseUp(int x, int y, unsigned button) +{ + drawing = false; +} + +void CardInput::OnTryExit(ExitMethod method) +{ + CloseActiveWindow(); + SelfDestruct(); +} diff --git a/src/gui/coin/CardInput.h b/src/gui/coin/CardInput.h new file mode 100644 index 000000000..def83f752 --- /dev/null +++ b/src/gui/coin/CardInput.h @@ -0,0 +1,44 @@ +#ifndef CARDINPUT_H +#define CARDINPUT_H + +#include "graphics/Pixel.h" +#include "graphics/Graphics.h" +#include "gui/interface/Window.h" + +namespace ui +{ +class Button; +class Textbox; +} +class CardInput : public ui::Window +{ + //pixel signature[50][250]; + VideoBuffer *signature; + bool drawing = false; + int step = 1; + int purchaseChance; + int amount; + + ui::Button *next; + std::vector textboxChecks; + bool signatureValid = false; + + void Next(); + void Step1(); + void Step2(); + void AttemptPurchase(); + void ClearComponents(int step); +public: + CardInput(int chance, int amount); + ~CardInput(); + virtual void OnDraw(); + virtual void OnTick(float dt); + + virtual void OnMouseMove(int x, int y, int dx, int dy); + virtual void OnMouseDown(int x, int y, unsigned button); + virtual void OnMouseUp(int x, int y, unsigned button); + + virtual void OnTryExit(ExitMethod method); +}; + +#endif // CARDINPUT_H diff --git a/src/gui/coin/Coin.cpp b/src/gui/coin/Coin.cpp new file mode 100644 index 000000000..26e51988f --- /dev/null +++ b/src/gui/coin/Coin.cpp @@ -0,0 +1,244 @@ +#include +#include +#include "Coin.h" +#include "CardInput.h" +#include "Format.h" +#include "Platform.h" +#include "Redeem.h" +#include "client/Client.h" +#include "client/Download.h" +#include "graphics/Graphics.h" +#include "simulation/Simulation.h" +#include "gui/dialogues/ConfirmPrompt.h" +#include "gui/dialogues/ErrorMessage.h" +#include "gui/dialogues/InformationMessage.h" +#include "gui/dialogues/TextPrompt.h" +#include "gui/game/GameModel.h" +#include "gui/interface/Button.h" +#include "gui/interface/Engine.h" +#include "gui/interface/Label.h" + +Coin::Coin(GameModel *gameModel): + ui::Window(ui::Point(-1, -1), ui::Point(500, 400)), + gameModel(gameModel) +{ + std::string labelText = "TPT has now gone free to play! Many elements are unlocked by default, but by using \brNEW\bw \xEA""owdercoins you " + "can unlock new elements and features never seen before. No need to get out your wallet though - \boyou can earn " + "coins just by playing TPT!\n\n" + "\bwWhy are you doing this?\n" + "\bgTimes have been hard recently - server costs are increasing due to the rise in bitcoin mining. " + "The tariffs placed by the US government on foreign explosives makers has also affected us significantly.\n" + "We also incurred large costs paying for the funeral of our server admin, Simon.\n\n" + "\bwWhat will the money go towards?\n" + "\bgThe money will go towards paying for new and upgraded servers, advertising, and entertainment expenses for jacob1 " + "and the other admins to keep us productive."; + + //int textsize = Graphics::textwidth(labelText.c_str()); + int height = Graphics::textwrapheight((char*)labelText.c_str(), 400); + ui::Label *label = new ui::Label(ui::Point(10, 15), ui::Point(400, height), labelText); + label->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + label->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + label->SetMultiline(true); + AddComponent(label); + + labelText = "\bo\xEA""owdercoins: " + format::NumberToString(Client::Ref().GetCoins()); + int textsize = Graphics::textwidth(labelText.c_str()); + powderCoins = new ui::Label(ui::Point(450 - textsize/2, 15), ui::Point(textsize, 16), labelText); + AddComponent(powderCoins); + + class BuyCoinsAction: public ui::ButtonAction + { + Coin * coin; + int chance; + int amount; + public: + BuyCoinsAction(Coin * coin, int chance, int amount) { this->coin = coin; this->chance = chance; this->amount = amount; } + void ActionCallback(ui::Button * sender) + { + //ConfirmPrompt::Blocking("Agree to ToS?", "test message asdf", "Confirm", true); + CardInput *card = new CardInput(chance, amount); + ui::Engine::Ref().ShowWindow(card); + } + }; + + struct coinData + { + int amount; + int chance; + std::string title; + //std::string description; + + coinData(int amount, int chance, std::string title): + amount(amount), + chance(chance), + title(title) + { + + } + }; + std::vector dataList = std::vector(); + dataList.push_back(coinData(100, 50, "$0.99 - basic package")); + dataList.push_back(coinData(200, 40, "$1.94 - save 2%")); + dataList.push_back(coinData(500, 30, "$4.74 - save 5%")); + dataList.push_back(coinData(1000, 20, "$10.99 - save 10% - BEST DEAL!")); + dataList.push_back(coinData(1500, 10, "$13.99 - ultra package")); + dataList.push_back(coinData(2500, 5, "$23.49 - used, 60,000 miles, no accidents")); + dataList.push_back(coinData(5000, 0, "$49.99 - 50 basic packages included!")); + dataList.push_back(coinData(9999, 0, "$94.99 - All proceeds from this option go to saving the whales")); + + ui::Button *button; + + int x = 10; + int y = 200; + for (coinData data : dataList) + { + std::stringstream buttonText; + buttonText << "\xEA"; + buttonText << data.amount; + button = new ui::Button(ui::Point(x, y), ui::Point(40, 25), buttonText.str()); + button->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + button->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + button->SetActionCallback(new BuyCoinsAction(this, data.chance, data.amount)); + AddComponent(button); + + label = new ui::Label(ui::Point(x + 45, y+2), ui::Point(200, 16), data.title); + label->SetMultiline(true); + label->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + label->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + AddComponent(label); + + if (x == 10) + x = 250; + else + { + x = 10; + y += 35; + } + } + + class OpenLinkAction : public ui::ButtonAction + { + std::string uri; + public: + OpenLinkAction(std::string uri) { this->uri = uri; } + void ActionCallback(ui::Button * sender) + { + Platform::OpenURI(uri); + } + }; + + button = new ui::Button(ui::Point(20, 375), ui::Point(90, 20), "\x0F\x14\xA0\xFE\xEB\x0E @PowderToy"); + button->SetActionCallback(new OpenLinkAction("https://twitter.com/PowderToy")); + AddComponent(button); + + button = new ui::Button(ui::Point(130, 375), ui::Point(90, 20), "\bb\xEC\bw PowderToy"); + button->SetActionCallback(new OpenLinkAction("https://www.facebook.com/PowderToy")); + AddComponent(button); + + button = new ui::Button(ui::Point(240, 375), ui::Point(90, 20), "\x0F\xFE\x47\x1A\xED\x0E PowderToy"); + button->SetActionCallback(new OpenLinkAction("https://www.youtube.com/watch?v=lcZwzlb2O_4")); + AddComponent(button); + + button = new ui::Button(ui::Point(350, 375), ui::Point(90, 20), "\x0F\xFE\x72\x1E\xEF\x0E /r/powdertoy"); + button->SetActionCallback(new OpenLinkAction("https://www.reddit.com/r/birdswitharms/")); + AddComponent(button); + + + class RedeemAction : public ui::ButtonAction + { + Simulation *simulation; + std::vector menus; + public: + RedeemAction(std::vector menus, Simulation *simulation) { this->menus = menus; this->simulation = simulation; } + void ActionCallback(ui::Button * sender) + { + Redeem *redeem = new Redeem(menus, simulation); + ui::Engine::Ref().ShowWindow(redeem); + } + }; + + button = new ui::Button(ui::Point(400, 49), ui::Point(100, 50), "REDEEM >"); + button->SetActionCallback(new RedeemAction(gameModel->GetMenuList(), gameModel->GetSimulation())); + AddComponent(button); + + class CodeAction : public ui::ButtonAction + { + public: + void ActionCallback(ui::Button * sender) + { + std::string code = TextPrompt::Blocking("Enter Code", "Enter a valid code to receive extra \xEA""owderCoins and other prizes", "", "", false); + if (code.find(' ') != code.npos || code.find('&') != code.npos) + { + new ErrorMessage("Invalid code", "Code cannot contain spaces"); + return; + } + + std::stringstream codeUrl; + codeUrl << "http://aprilfools.starcatcher.us/Moo/AprilFool.lua"; + codeUrl << "?username=" << Client::Ref().GetAuthUser().Username; + codeUrl << "&code=" << code; + Download *download = new Download(codeUrl.str()); + // Lua on server side doesn't understand this format and I don't have the time to figure out how to make it understand this + /*std::map postData = { + {"username", Client::Ref().GetAuthUser().Username}, + {"code", code} + };*/ + //download->AddPostData(postData); + download->Start(); + int length, status; + char *data = download->Finish(&length, &status); + if (status != 200) + { + new ErrorMessage("Server error", "Recieved http error code " + format::NumberToString(status)); + return; + } + if (length == 0) + { + new ErrorMessage("Invalid code", "This code is not valid"); + return; + } + + char *data2 = new char[length+1]; + strncpy(data2, data, length); + data2[length] = 0; + + int amount = format::StringToNumber(data2); + if (amount == 0) + { + new ErrorMessage("Server error", "Recieved message from server: " + std::string(data2)); + return; + } + Client::Ref().AddCoins(amount); + new InformationMessage("Received Coins!", "You received " + std::string(data2) + " coins! New balance: " + + format::NumberToString(Client::Ref().GetCoins()) + " \xEA""owdercoins", false); + //std::cout << data2 << std::endl; + } + }; + + button = new ui::Button(ui::Point(400, 98), ui::Point(100, 50), "CODE >"); + button->SetActionCallback(new CodeAction()); + AddComponent(button); +} + +void Coin::OnDraw() +{ + Graphics * g = GetGraphics(); + + g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); + g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); + + g->drawrect(Position.X+400, Position.Y, Size.X-400, 50, 200, 200, 200, 255); +} + +void Coin::OnTick(float dt) +{ + std::string text = "\bo\xEA""owdercoins: " + format::NumberToString(Client::Ref().GetCoins()); + powderCoins->SetText(text); +} + +void Coin::OnTryExit(ExitMethod method) +{ + CloseActiveWindow(); + SelfDestruct(); + gameModel->BuildMenus(); +} diff --git a/src/gui/coin/Coin.h b/src/gui/coin/Coin.h new file mode 100644 index 000000000..3ec9e9717 --- /dev/null +++ b/src/gui/coin/Coin.h @@ -0,0 +1,22 @@ +#ifndef COIN_H +#define COIN_H + +#include "gui/interface/Window.h" + +class GameModel; +namespace ui +{ + class Label; +} +class Coin : public ui::Window +{ + GameModel *gameModel; + ui::Label *powderCoins; +public: + Coin(GameModel *gameModel); + virtual void OnDraw(); + virtual void OnTick(float dt); + virtual void OnTryExit(ExitMethod method); +}; + +#endif // COIN_H diff --git a/src/gui/coin/Promote.cpp b/src/gui/coin/Promote.cpp new file mode 100644 index 000000000..6eb8d18fa --- /dev/null +++ b/src/gui/coin/Promote.cpp @@ -0,0 +1,151 @@ +#include +#include "Promote.h" +#include "Format.h" +#include "client/Client.h" +#include "client/Download.h" +#include "client/MD5.h" +#include "graphics/Graphics.h" +#include "gui/Style.h" +#include "simulation/Simulation.h" + +#include "gui/dialogues/ConfirmPrompt.h" +#include "gui/dialogues/InformationMessage.h" +#include "gui/dialogues/ErrorMessage.h" +#include "gui/game/Tool.h" +#include "gui/game/Menu.h" +#include "gui/interface/Button.h" +#include "gui/interface/Engine.h" +#include "gui/interface/Label.h" + +#ifndef SERVERSALT +#define SERVERSALT "Pepper" +#endif + +Promote::Promote(int saveID): + ui::Window(ui::Point(-1, -1), ui::Point(300, 235)), + saveID(saveID) +{ + std::string labelText = "You can promote saves to the front page using \xEA""owdercoins! Your first save is only 100 " + "\xEA""owdercoins to promote, with future promotions costing more.\n\nThere are only a few requirements for promoting " + "a save to FP. It must have never been demoted or disabled; and it must have a positive total amount of votes. It also must be published.\n\n" + "\bgNotes on price: In order to limit abuse, each promotion will cost 10x the amount of \xEA""owdercoins as the last. " + "Price will reset back to 100 \xEA""owdercoins at midnight UTC on Friday each week. Prices are subject to change without " + "notice.\n\n" + "\bwClick Continue to promote this save. Processing may take 10 seconds or more."; + + int height = Graphics::textwrapheight((char*)labelText.c_str(), 400); + ui::Label *label = new ui::Label(ui::Point(10, 35), ui::Point(280, height), labelText); + label->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + label->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + label->SetMultiline(true); + AddComponent(label); + + + // Copy paste from ConfirmPrompt, maybe I should just use that instead but I already created these files + class CloseAction: public ui::ButtonAction + { + public: + Promote * promote; + bool result; + CloseAction(Promote * promote_, bool result_) { promote = promote_; result = result_; } + void ActionCallback(ui::Button * sender) + { + promote->CloseActiveWindow(); + promote->Callback(result); + promote->SelfDestruct(); + } + }; + + ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X-75, 16), "Cancel"); + cancelButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + cancelButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + cancelButton->Appearance.BorderInactive = ui::Colour(200, 200, 200); + cancelButton->SetActionCallback(new CloseAction(this, false)); + AddComponent(cancelButton); + SetCancelButton(cancelButton); + + ui::Button * okayButton = new ui::Button(ui::Point(Size.X-76, Size.Y-16), ui::Point(76, 16), "Continue"); + okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; + okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + okayButton->Appearance.TextInactive = style::Colour::WarningTitle; + okayButton->SetActionCallback(new CloseAction(this, true)); + AddComponent(okayButton); + SetOkayButton(okayButton); + + ui::Engine::Ref().ShowWindow(this); +} + +void Promote::Callback(bool confirmed) +{ + //Client::Ref().SetCoins(100000); + if (!confirmed) + { + new InformationMessage("Canceled", "You will not be charged", false); + return; + } + std::stringstream promoteUrl; + promoteUrl << "http://aprilfools.starcatcher.us/Moo/PromoteSave.lua"; + promoteUrl << "?username=" << Client::Ref().GetAuthUser().Username; + + std::stringstream random; + random << rand() << rand() << rand() << rand(); + promoteUrl << "&random=" << random.str().substr(0, 20); + + int numCoins = Client::Ref().GetCoins(); + + std::string salt = SERVERSALT; + salt += "-" + Client::Ref().GetAuthUser().Username; + salt += "-" + random.str().substr(0, 20); + salt += "-" + format::NumberToString(numCoins); + std::cout << salt << std::endl; + char saltMd5[33]; + md5_ascii(saltMd5, (const unsigned char *)salt.c_str(), salt.length()); + promoteUrl << "&hash=" << std::string(saltMd5); + promoteUrl << "&numcoins=" << numCoins; + promoteUrl << "&saveid=" << saveID; + + Download *download = new Download(promoteUrl.str()); + download->Start(); + int length, status; + char *data = download->Finish(&length, &status); + if (status != 200) + { + new ErrorMessage("Server error", "Recieved http error code " + format::NumberToString(status)); + return; + } + if (length == 0) + { + new ErrorMessage("Internal Server Error", "This isn't supposed to happen, please bug the admins about this"); + return; + } + + char *data2 = new char[length+1]; + strncpy(data2, data, length); + data2[length] = 0; + + int amount = format::StringToNumber(data2); + if (amount == 0) + { + new InformationMessage("Message from server", std::string(data2), false); + } + else + { + Client::Ref().AddCoins(-amount); + new InformationMessage("Promoted!", "Save will appear on front page momentarily. New \xEA""owdercoins balance: " + + format::NumberToString(Client::Ref().GetCoins()), false); + } +} + +void Promote::OnDraw() +{ + Graphics * g = GetGraphics(); + + g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); + g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); +} + +void Promote::OnTryExit(ExitMethod method) +{ + CloseActiveWindow(); + SelfDestruct(); +} diff --git a/src/gui/coin/Promote.h b/src/gui/coin/Promote.h new file mode 100644 index 000000000..4ab671a5c --- /dev/null +++ b/src/gui/coin/Promote.h @@ -0,0 +1,17 @@ +#ifndef PROMOTE_H +#define PROMOTE_H + +#include "gui/interface/Window.h" + +class Promote : public ui::Window +{ + int saveID; +public: + Promote(int saveID); + virtual void OnDraw(); + virtual void OnTryExit(ExitMethod method); + + void Callback(bool confirmed); +}; + +#endif // PROMOTE_H diff --git a/src/gui/coin/Redeem.cpp b/src/gui/coin/Redeem.cpp new file mode 100644 index 000000000..fa104a16a --- /dev/null +++ b/src/gui/coin/Redeem.cpp @@ -0,0 +1,119 @@ +#include +#include "Redeem.h" +#include "Format.h" +#include "client/Client.h" +#include "graphics/Graphics.h" +#include "simulation/Simulation.h" +#include "gui/dialogues/ConfirmPrompt.h" +#include "gui/dialogues/ErrorMessage.h" +#include "gui/game/Tool.h" +#include "gui/game/Menu.h" +#include "gui/game/ToolButton.h" +#include "gui/interface/Button.h" +#include "gui/interface/Engine.h" +#include "gui/interface/Label.h" + +class PackRedeem : public ui::ButtonAction +{ + std::vector toolList; + int price; + Simulation * sim; + +public: + PackRedeem(std::vector toolList, int price, Simulation *sim): + toolList(toolList), + price(price), + sim(sim) + { + + } + + void ActionCallback(ui::Button * sender_) + { + int numCoins = Client::Ref().GetCoins(); + std::string unlockPrice = format::NumberToString(price); + if (numCoins < price) + { + new ErrorMessage("Cannot afford pack", "This pack requires " + unlockPrice + + " \xEA""owdercoins to purchase.\n\nYou have " + format::NumberToString(numCoins) + " coins"); + } + else + { + bool buy = ConfirmPrompt::Blocking("Buy element pack?", "Buy this element for " + unlockPrice + " \xEA" + "owdercoins? You will have " + format::NumberToString(numCoins - price) + " \xEA" + "owdercoins after this transaction."); + if (buy) + { + Client::Ref().AddCoins(-price); + for (Tool * tool : toolList) + { + int toolId = tool->GetToolID(); + if (toolId > 0 && toolId < PT_NUM) + sim->elements[toolId].Unlocked = true; + } + } + } + sender_->GetParentWindow()->CloseActiveWindow(); + sender_->GetParentWindow()->SelfDestruct(); + } +}; + +Redeem::Redeem(std::vector menus, Simulation *simulation): + ui::Window(ui::Point(-1, -1), ui::Point(300, 300)), + menus(menus), + simulation(simulation) +{ + int y = 10; + std::vector menuPacks = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + for (int pack : menuPacks) + { + Tool * tool = nullptr; + int count = 0; + int price = 0; + for (Tool *menuTool : menus[pack]->GetToolList()) + if (!menuTool->unlocked) + { + if (!count++) + tool = menuTool; + price += menuTool->unlockPrice; + } + if (!tool) + continue; + + std::string desc = menus[pack]->GetDescription() + " Pack: "; + int textSize = Graphics::textwidth(desc.c_str()); + ui::Label * label = new ui::Label(ui::Point(20, y), ui::Point(textSize, 16), desc); + AddComponent(label); + + ToolButton * tempButton = new ToolButton(ui::Point(20 + textSize, y), ui::Point(30, 18), tool->GetName(), tool->GetIdentifier(), tool->GetDescription()); + tempButton->Appearance.BackgroundInactive = ui::Colour(tool->colRed, tool->colGreen, tool->colBlue); + // 1.1 times normal price for the added convenience of buying all the elements at once + tempButton->SetActionCallback(new PackRedeem(menus[pack]->GetToolList(), price * 1.1, simulation)); + tempButton->SetUnlocked(tool->unlocked); + AddComponent(tempButton); + + if (count > 1) + { + desc = " and " + format::NumberToString(count-1) + " others"; + int textSize2 = Graphics::textwidth(desc.c_str()); + label = new ui::Label(ui::Point(20 + textSize + 30, y), ui::Point(textSize2, 16), desc); + AddComponent(label); + } + + y += 25; + } +} + +void Redeem::OnDraw() +{ + Graphics * g = GetGraphics(); + + g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3); + g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); +} + +void Redeem::OnTryExit(ExitMethod method) +{ + CloseActiveWindow(); + SelfDestruct(); +} diff --git a/src/gui/coin/Redeem.h b/src/gui/coin/Redeem.h new file mode 100644 index 000000000..db01659d6 --- /dev/null +++ b/src/gui/coin/Redeem.h @@ -0,0 +1,19 @@ +#ifndef REDEEM_H +#define REDEEM_H + +#include +#include "gui/interface/Window.h" + +class Simulation; +class Menu; +class Redeem : public ui::Window +{ + std::vector menus; + Simulation *simulation; +public: + Redeem(std::vector tools, Simulation *simulation); + virtual void OnDraw(); + virtual void OnTryExit(ExitMethod method); +}; + +#endif // REDEEM_H diff --git a/src/gui/dialogues/ConfirmPrompt.cpp b/src/gui/dialogues/ConfirmPrompt.cpp index 0fa00ff1c..e7a6ece85 100644 --- a/src/gui/dialogues/ConfirmPrompt.cpp +++ b/src/gui/dialogues/ConfirmPrompt.cpp @@ -68,10 +68,16 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, ConfirmDial MakeActiveWindow(); } -ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, std::string buttonText, ConfirmDialogueCallback * callback_): +ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, std::string buttonText, ConfirmDialogueCallback * callback_, bool large): ui::Window(ui::Point(-1, -1), ui::Point(250, 50)), callback(callback_) { + if (large) //Maybe also use this large mode for changelogs eventually, or have it as a customizable size? + { + Size.X += 200; + Size.Y += 215; + } + ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 15), title); titleLabel->SetTextColour(style::Colour::WarningTitle); titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; @@ -90,10 +96,13 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, std::string messagePanel->InnerSize = ui::Point(messagePanel->Size.X, messageLabel->Size.Y+4); - if (messageLabel->Size.Y < messagePanel->Size.Y) - messagePanel->Size.Y = messageLabel->Size.Y+4; - Size.Y += messagePanel->Size.Y+12; - Position.Y = (ui::Engine::Ref().GetHeight()-Size.Y)/2; + if (!large) + { + if (messageLabel->Size.Y < messagePanel->Size.Y) + messagePanel->Size.Y = messageLabel->Size.Y+4; + Size.Y += messagePanel->Size.Y+12; + Position.Y = (ui::Engine::Ref().GetHeight()-Size.Y)/2; + } class CloseAction: public ui::ButtonAction { @@ -130,7 +139,7 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, std::string MakeActiveWindow(); } -bool ConfirmPrompt::Blocking(std::string title, std::string message, std::string buttonText) +bool ConfirmPrompt::Blocking(std::string title, std::string message, std::string buttonText, bool large) { class BlockingPromptCallback: public ConfirmDialogueCallback { public: @@ -146,7 +155,7 @@ bool ConfirmPrompt::Blocking(std::string title, std::string message, std::string virtual ~BlockingPromptCallback() { } }; bool result; - new ConfirmPrompt(title, message, buttonText, new BlockingPromptCallback(result)); + new ConfirmPrompt(title, message, buttonText, new BlockingPromptCallback(result), large); EngineProcess(); return result; } diff --git a/src/gui/dialogues/ConfirmPrompt.h b/src/gui/dialogues/ConfirmPrompt.h index 62aff7fd2..7d02a2237 100644 --- a/src/gui/dialogues/ConfirmPrompt.h +++ b/src/gui/dialogues/ConfirmPrompt.h @@ -9,8 +9,8 @@ class ConfirmPrompt: public ui::Window { public: enum DialogueResult { ResultCancel, ResultOkay }; ConfirmPrompt(std::string title, std::string message, ConfirmDialogueCallback * callback_ = NULL); - ConfirmPrompt(std::string title, std::string message, std::string buttonText, ConfirmDialogueCallback * callback_ = NULL); - static bool Blocking(std::string title, std::string message, std::string buttonText = "Confirm"); + ConfirmPrompt(std::string title, std::string message, std::string buttonText, ConfirmDialogueCallback * callback_ = NULL, bool large = false); + static bool Blocking(std::string title, std::string message, std::string buttonText = "Confirm", bool large = false); virtual void OnDraw(); virtual ~ConfirmPrompt(); ConfirmDialogueCallback * callback; diff --git a/src/gui/elementsearch/ElementSearchActivity.cpp b/src/gui/elementsearch/ElementSearchActivity.cpp index 33cabfd03..38e2cd050 100644 --- a/src/gui/elementsearch/ElementSearchActivity.cpp +++ b/src/gui/elementsearch/ElementSearchActivity.cpp @@ -1,5 +1,9 @@ #include #include "ElementSearchActivity.h" +#include "Format.h" +#include "client/Client.h" +#include "gui/dialogues/ConfirmPrompt.h" +#include "gui/dialogues/ErrorMessage.h" #include "gui/interface/Textbox.h" #include "gui/interface/Label.h" #include "gui/interface/Keys.h" @@ -17,7 +21,31 @@ public: void ActionCallback(ui::Button * sender_) { ToolButton *sender = (ToolButton*)sender_; - if(sender->GetSelectionState() >= 0 && sender->GetSelectionState() <= 2) + if (!tool->unlocked) + { + int numCoins = Client::Ref().GetCoins(); + std::string unlockPrice = format::NumberToString(tool->unlockPrice); + if (numCoins < tool->unlockPrice) + { + new ErrorMessage("This element is locked", "This element is locked and requires " + unlockPrice + + " \xEA""owdercoins to purchase.\n\nYou have " + format::NumberToString(numCoins) + " coins"); + } + else + { + bool buy = ConfirmPrompt::Blocking("This element is locked", "Buy this element for " + unlockPrice + " \xEA" + "owdercoins? You will have " + format::NumberToString(numCoins - tool->unlockPrice) + " \xEA" + "owdercoins after this transaction.\n\nFor more purchaseable items and sets, click the \xEA" + "icon on the bottom bar."); + if (buy) + { + Client::Ref().AddCoins(-tool->unlockPrice); + a->UnlockElement(tool->GetToolID()); + a->SetActiveTool(sender->GetSelectionState(), tool); + } + } + return; + } + if (sender->GetSelectionState() >= 0 && sender->GetSelectionState() <= 2) a->SetActiveTool(sender->GetSelectionState(), tool); } }; @@ -143,6 +171,7 @@ void ElementSearchActivity::searchTools(std::string query) tempButton->Appearance.SetTexture(tempTexture); tempButton->Appearance.BackgroundInactive = ui::Colour(tool->colRed, tool->colGreen, tool->colBlue); tempButton->SetActionCallback(new ToolAction(this, tool)); + tempButton->SetUnlocked(tool->unlocked); if(gameController->GetActiveTool(0) == tool) { @@ -189,6 +218,11 @@ void ElementSearchActivity::SetActiveTool(int selectionState, Tool * tool) exit = true; } +void ElementSearchActivity::UnlockElement(int element) +{ + gameController->UnlockElement(element); +} + void ElementSearchActivity::OnDraw() { Graphics * g = GetGraphics(); diff --git a/src/gui/elementsearch/ElementSearchActivity.h b/src/gui/elementsearch/ElementSearchActivity.h index bf9af235a..e898f3328 100644 --- a/src/gui/elementsearch/ElementSearchActivity.h +++ b/src/gui/elementsearch/ElementSearchActivity.h @@ -32,6 +32,7 @@ public: Tool * GetFirstResult() { return firstResult; } ElementSearchActivity(GameController * gameController, std::vector tools); void SetActiveTool(int selectionState, Tool * tool); + void UnlockElement(int element); virtual ~ElementSearchActivity(); virtual void OnTick(float dt); virtual void OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt); diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index f3ae7b68d..2274e5d7f 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -38,6 +38,15 @@ #include "lua/TPTScriptInterface.h" #endif + +#include "client/MD5.h" +#include "gui/coin/Coin.h" +#include "gui/coin/Promote.h" + +#ifndef SALT +#define SALT "HBtzeBMtXau2xse2D" +#endif + using namespace std; class GameController::SearchCallback: public ControllerCallback @@ -167,6 +176,71 @@ GameController::GameController(): debugInfo.push_back(new ElementPopulationDebug(0x2, gameModel->GetSimulation())); debugInfo.push_back(new DebugLines(0x4, gameView, this)); debugInfo.push_back(new ParticleDebug(0x8, gameModel->GetSimulation(), gameModel)); + + + int coins = Client::Ref().GetPrefInteger("Coins.coins", 0); + if (coins < 0) + coins = 0; + if (coins) + { + std::string salt = Client::Ref().GetPrefString("Coins.salt", ""); + + std::string expectedsalt = SALT; + if (Client::Ref().GetAuthUser().UserID) + expectedsalt += "-" + Client::Ref().GetAuthUser().UserID; + expectedsalt += "-" + coins; + + char saltMd5[33]; + md5_ascii(saltMd5, (const unsigned char *)expectedsalt.c_str(), expectedsalt.length()); + std::string expectedSaltStr = saltMd5; + + if (salt != expectedSaltStr) + { + gameModel->Log("Coins have been reset due to login status change or tampering, expected " + expectedSaltStr + ", got " + salt + ", current coins " + format::NumberToString(coins), false); + coins = 0; + } + } + Client::Ref().SetCoins(coins); + + std::vector unlockedElements = Client::Ref().GetPrefIntegerArray("Coins.UnlockedElements"); + int unlockedSalt = 0; + for (int i = 0; i < PT_NUM; i++) + { + try + { + if (unlockedElements.at(i)) + unlockedSalt += i << (i%20); + } + catch (std::exception &e) + { + gameModel->Log("Unlocked elements have been reset due to preference loading exception", false); + return; + } + } + + std::string salt = Client::Ref().GetPrefString("Coins.UnlockedSalt", ""); + if (!salt.length()) + return; + + std::string expectedsalt = SALT; + expectedsalt += "-" + format::NumberToString(unlockedSalt); + char saltMd5[33]; + md5_ascii(saltMd5, (const unsigned char *)expectedsalt.c_str(), expectedsalt.length()); + std::string expectedSaltStr = saltMd5; + + if (salt != expectedSaltStr) + { + gameModel->Log("Unlocked elements have been reset due to unauthorized tampering", false); + return; + } + for (int i = 0; i < PT_NUM; i++) + gameModel->GetSimulation()->elements[i].Unlocked = unlockedElements[i] ? true : false; + gameModel->BuildMenus(); + if (gameModel->GetSimulation()->elements[0].Unlocked) + { + this->SetActiveTool(1, "DEFAULT_PT_NONE"); + this->SetActiveTool(3, "DEFAULT_PT_NONE"); + } } GameController::~GameController() @@ -223,6 +297,34 @@ GameController::~GameController() { delete *iter; } + + int coins = Client::Ref().GetCoins(); + Client::Ref().SetPref("Coins.coins", coins); + std::string salt = SALT; + if (Client::Ref().GetAuthUser().UserID) + salt += "-" + Client::Ref().GetAuthUser().UserID; + salt += "-" + coins; + + char saltMd5[33]; + md5_ascii(saltMd5, (const unsigned char *)salt.c_str(), salt.length()); + Client::Ref().SetPref("Coins.salt", std::string(saltMd5)); + + std::vector unlockedElements; + int unlockedSalt = 0; + for (int i = 0; i < PT_NUM; i++) + { + bool unlocked = gameModel->GetSimulation()->elements[i].Unlocked; + unlockedElements.push_back(unlocked ? 1 : 0); + if (unlocked) + unlockedSalt += i << (i%20); + } + Client::Ref().SetPref("Coins.UnlockedElements", std::vector(unlockedElements.begin(), unlockedElements.end())); + + salt = SALT; + salt += "-" + format::NumberToString(unlockedSalt); + md5_ascii(saltMd5, (const unsigned char *)salt.c_str(), salt.length()); + Client::Ref().SetPref("Coins.UnlockedSalt", std::string(saltMd5)); + delete gameModel; if (gameView->CloseActiveWindow()) { @@ -230,6 +332,15 @@ GameController::~GameController() } } +void GameController::UnlockElement(int ID) +{ + if (ID >= 0 && ID < PT_NUM) + { + gameModel->GetSimulation()->elements[ID].Unlocked = 1; + gameModel->BuildMenus(); + } +} + void GameController::HistoryRestore() { std::deque history = gameModel->GetHistory(); @@ -1375,6 +1486,12 @@ void GameController::OpenTags() } } +void GameController::OpenCoin() +{ + Coin *coin = new Coin(gameModel); + ui::Engine::Ref().ShowWindow(coin); +} + void GameController::OpenStamps() { localBrowser = new LocalBrowserController(new StampsCallback(this)); diff --git a/src/gui/game/GameController.h b/src/gui/game/GameController.h index 48560190d..e732717a0 100644 --- a/src/gui/game/GameController.h +++ b/src/gui/game/GameController.h @@ -70,6 +70,8 @@ public: void Tick(); void Exit(); + void UnlockElement(int ID); + void Install(); void HistoryRestore(); @@ -123,6 +125,7 @@ public: void OpenLogin(); void OpenProfile(); void OpenTags(); + void OpenCoin(); void OpenSavePreview(int saveID, int saveDate, bool instant); void OpenSavePreview(); void OpenLocalSaveWindow(bool asCurrent); diff --git a/src/gui/game/GameModel.cpp b/src/gui/game/GameModel.cpp index f81ecefc6..5eb000882 100644 --- a/src/gui/game/GameModel.cpp +++ b/src/gui/game/GameModel.cpp @@ -298,6 +298,8 @@ void GameModel::BuildMenus() { extraElementTools.push_back(tempTool); } + tempTool->unlocked = sim->elements[i].Unlocked; + tempTool->unlockPrice = sim->elements[i].UnlockPrice; elementTools.push_back(tempTool); } } @@ -306,6 +308,7 @@ void GameModel::BuildMenus() for(int i = 0; i < NGOL; i++) { Tool * tempTool = new ElementTool(PT_LIFE|PMAPID(i), sim->gmenu[i].name, std::string(sim->gmenu[i].description), PIXR(sim->gmenu[i].colour), PIXG(sim->gmenu[i].colour), PIXB(sim->gmenu[i].colour), "DEFAULT_PT_LIFE_"+std::string(sim->gmenu[i].name)); + tempTool->unlocked = sim->elements[PT_LIFE].Unlocked; menuList[SC_LIFE]->AddTool(tempTool); } @@ -345,10 +348,11 @@ void GameModel::BuildMenus() decoToolset[3] = GetToolFromIdentifier("DEFAULT_PT_NONE"); //Set default tools + std::string eraser = sim->elements[PT_NONE].Unlocked ? "DEFAULT_PT_NONE" : "DEFAULT_WL_ERASEA"; regularToolset[0] = GetToolFromIdentifier("DEFAULT_PT_DUST"); - regularToolset[1] = GetToolFromIdentifier("DEFAULT_PT_NONE"); + regularToolset[1] = GetToolFromIdentifier(eraser); regularToolset[2] = GetToolFromIdentifier("DEFAULT_UI_SAMPLE"); - regularToolset[3] = GetToolFromIdentifier("DEFAULT_PT_NONE"); + regularToolset[3] = GetToolFromIdentifier(eraser); if(activeToolIdentifiers[0].length()) diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index db2db591d..e46368859 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -15,8 +15,9 @@ #include "gui/search/Thumbnail.h" #include "simulation/SaveRenderer.h" #include "simulation/SimulationData.h" -#include "gui/dialogues/InformationMessage.h" #include "gui/dialogues/ConfirmPrompt.h" +#include "gui/dialogues/ErrorMessage.h" +#include "gui/dialogues/InformationMessage.h" #include "client/SaveFile.h" #include "Format.h" #include "QuickOptions.h" @@ -24,7 +25,6 @@ #include "DecorationTool.h" #include "Favorite.h" - class SplitButton; class SplitButtonAction { @@ -333,13 +333,29 @@ GameView::GameView(): v->c->OpenTags(); } }; - tagSimulationButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(227, 15), "[no tags set]", "Add simulation tags"); + tagSimulationButton = new ui::Button(ui::Point(currentX, Size.Y-16), ui::Point(209, 15), "[no tags set]", "Add simulation tags"); tagSimulationButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tagSimulationButton->SetIcon(IconTag); //currentX+=252; tagSimulationButton->SetActionCallback(new TagSimulationAction(this)); AddComponent(tagSimulationButton); + class CoinAction : public ui::ButtonAction + { + GameView * v; + public: + CoinAction(GameView * _v) { v = _v; } + void ActionCallback(ui::Button * sender) + { + v->c->OpenCoin(); + } + }; + ui::Button *coinButton = new ui::Button(ui::Point(Size.X-177, Size.Y-16), ui::Point(17, 15), "", "Open thing"); + coinButton->SetIcon(IconCoin); + coinButton->Appearance.Margin.Left += 2; + coinButton->SetActionCallback(new CoinAction(this)); + AddComponent(coinButton); + class ClearSimAction : public ui::ButtonAction { GameView * v; @@ -541,6 +557,29 @@ public: ToolAction(GameView * _v, Tool * tool_) { v = _v; tool = tool_; } void ActionCallback(ui::Button * sender_) { + if (!tool->unlocked) + { + int numCoins = Client::Ref().GetCoins(); + std::string unlockPrice = format::NumberToString(tool->unlockPrice); + if (numCoins < tool->unlockPrice) + { + new ErrorMessage("This element is locked", "This element is locked and requires " + unlockPrice + + " \xEA""owdercoins to purchase.\n\nYou have " + format::NumberToString(numCoins) + " coins"); + } + else + { + bool buy = ConfirmPrompt::Blocking("This element is locked", "Buy this element for " + unlockPrice + " \xEA" + "owdercoins? You will have " + format::NumberToString(numCoins - tool->unlockPrice) + " \xEA" + "owdercoins after this transaction.\n\nFor more purchaseable items and sets, click the \xEA" + "icon on the bottom bar."); + if (buy) + { + Client::Ref().AddCoins(-tool->unlockPrice); + v->c->UnlockElement(tool->GetToolID()); + } + } + return; + } ToolButton *sender = (ToolButton*)sender_; if (v->ShiftBehaviour() && v->CtrlBehaviour() && !v->AltBehaviour()) { @@ -794,6 +833,7 @@ void GameView::NotifyToolListChanged(GameModel * sender) tempButton->Appearance.HorizontalAlign = ui::Appearance::AlignCentre; tempButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + tempButton->SetUnlocked(toolList[i]->unlocked); AddComponent(tempButton); toolButtons.push_back(tempButton); } @@ -1135,6 +1175,8 @@ void GameView::updateToolButtonScroll() void GameView::OnMouseMove(int x, int y, int dx, int dy) { + lastActivity = GetTicks(); + bool newMouseInZoom = c->MouseInZoom(ui::Point(x, y)); mousePosition = c->PointTranslate(ui::Point(x, y)); currentMouse = ui::Point(x, y); @@ -1183,6 +1225,8 @@ void GameView::OnMouseMove(int x, int y, int dx, int dy) void GameView::OnMouseDown(int x, int y, unsigned button) { + lastActivity = GetTicks(); + currentMouse = ui::Point(x, y); if (altBehaviour && !shiftBehaviour && !ctrlBehaviour) button = SDL_BUTTON_MIDDLE; @@ -1385,6 +1429,8 @@ void GameView::BeginStampSelection() void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { + lastActivity = GetTicks(); + if (introText > 50) { introText = 50; @@ -1701,6 +1747,23 @@ void GameView::OnBlur() void GameView::OnTick(float dt) { + if (lastCoinEarned == 0) + lastCoinEarned = GetTicks() + 6000; + int timeDiff = GetTicks() - lastCoinEarned; + if (timeDiff > 12000) + lastCoinEarned = GetTicks() + 6000; + else if (timeDiff > 6000) + { + if (lastActivity > lastCoinEarned) + { + Client::Ref().AddCoins(1); + std::cout << "earned coin" << std::endl; + } + else + std::cout << "no coin due to inactivity" << std::endl; + lastCoinEarned = GetTicks(); + } + if (selectMode == PlaceSave && !placeSaveThumb) selectMode = SelectNone; if (zoomEnabled && !zoomCursorFixed) diff --git a/src/gui/game/GameView.h b/src/gui/game/GameView.h index d94b927cb..81f1a8fc0 100644 --- a/src/gui/game/GameView.h +++ b/src/gui/game/GameView.h @@ -33,6 +33,9 @@ class GameModel; class GameView: public ui::Window { private: + unsigned int lastCoinEarned = 0; + unsigned int lastActivity = 0; + bool isMouseDown; bool skipDraw; bool zoomEnabled; diff --git a/src/gui/game/Tool.h b/src/gui/game/Tool.h index 84fb38e85..490f1ae12 100644 --- a/src/gui/game/Tool.h +++ b/src/gui/game/Tool.h @@ -24,6 +24,8 @@ protected: std::string identifier; public: int colRed, colGreen, colBlue; + bool unlocked = true; + int unlockPrice = 20; Tool(int id, string name, string description, int r, int g, int b, std::string identifier, VideoBuffer * (*textureGen)(int, int, int) = NULL); int GetToolID() { return toolID; } diff --git a/src/gui/game/ToolButton.cpp b/src/gui/game/ToolButton.cpp index 3557dc717..8c833c758 100644 --- a/src/gui/game/ToolButton.cpp +++ b/src/gui/game/ToolButton.cpp @@ -27,12 +27,15 @@ void ToolButton::OnMouseUnclick(int x, int y, unsigned int button) if(isButtonDown) { isButtonDown = false; - if(button == SDL_BUTTON_LEFT) - SetSelectionState(0); - if(button == SDL_BUTTON_RIGHT) - SetSelectionState(1); - if(button == SDL_BUTTON_MIDDLE) - SetSelectionState(2); + if (unlocked) + { + if (button == SDL_BUTTON_LEFT) + SetSelectionState(0); + if (button == SDL_BUTTON_RIGHT) + SetSelectionState(1); + if (button == SDL_BUTTON_MIDDLE) + SetSelectionState(2); + } DoAction(); } } @@ -65,7 +68,9 @@ void ToolButton::Draw(const ui::Point& screenPos) { g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, Appearance.BorderInactive.Red, Appearance.BorderInactive.Green, Appearance.BorderInactive.Blue, Appearance.BorderInactive.Alpha); } - if (Favorite::Ref().IsFavorite(toolIdentifier)) + if (!unlocked) + g->drawtext(screenPos.X, screenPos.Y, "\xE9", Appearance.BorderFavorite.Red, Appearance.BorderFavorite.Green, Appearance.BorderFavorite.Blue, Appearance.BorderFavorite.Alpha); + else if (Favorite::Ref().IsFavorite(toolIdentifier)) { g->drawtext(screenPos.X, screenPos.Y, "\xE8", Appearance.BorderFavorite.Red, Appearance.BorderFavorite.Green, Appearance.BorderFavorite.Blue, Appearance.BorderFavorite.Alpha); } diff --git a/src/gui/game/ToolButton.h b/src/gui/game/ToolButton.h index d2a8abccb..a751bb9ec 100644 --- a/src/gui/game/ToolButton.h +++ b/src/gui/game/ToolButton.h @@ -6,6 +6,7 @@ class ToolButton: public ui::Button { int currentSelection; + bool unlocked = true; std::string toolIdentifier; public: ToolButton(ui::Point position, ui::Point size, std::string text_, std::string toolIdentifier, std::string toolTip = ""); @@ -15,6 +16,8 @@ public: virtual void Draw(const ui::Point& screenPos); void SetSelectionState(int state); int GetSelectionState(); + void SetUnlocked(bool unlocked) { this->unlocked = unlocked; } + bool GetUnlocked() { return unlocked; } virtual ~ToolButton(); }; diff --git a/src/gui/interface/DropDown.cpp b/src/gui/interface/DropDown.cpp index 53612a782..a79cb0428 100644 --- a/src/gui/interface/DropDown.cpp +++ b/src/gui/interface/DropDown.cpp @@ -4,6 +4,7 @@ #include "Button.h" #include "DropDown.h" #include "gui/interface/Window.h" +#include "gui/interface/ScrollPanel.h" namespace ui { @@ -29,21 +30,30 @@ public: } }; DropDownWindow(DropDown * dropDown): - Window(ui::Point(dropDown->Position.X+dropDown->GetParentWindow()->Position.X-5, dropDown->Position.Y+dropDown->GetParentWindow()->Position.Y-3), ui::Point(dropDown->Size.X+10, 1+dropDown->options.size()*16)), + Window(ui::Point(dropDown->Position.X+dropDown->GetParentWindow()->Position.X-5, dropDown->Position.Y+dropDown->GetParentWindow()->Position.Y-3), ui::Point(dropDown->Size.X+25, 1+dropDown->options.size()*16)), dropDown(dropDown), appearance(dropDown->Appearance) { + ui::ScrollPanel *messagePanel = new ui::ScrollPanel(ui::Point(0, 0), ui::Point(Size.X-8, dropDown->GetParentWindow()->Size.Y - dropDown->Position.Y + 30)); + AddComponent(messagePanel); + int currentY = 1; for (size_t i = 0; i < dropDown->options.size(); i++) { - Button * tempButton = new Button(Point(1, currentY), Point(Size.X-2, 16), dropDown->options[i].first); + Button * tempButton = new Button(Point(1, currentY), Point(Size.X-17, 16), dropDown->options[i].first); tempButton->Appearance = appearance; if (i) tempButton->Appearance.Border = ui::Border(0, 1, 1, 1); tempButton->SetActionCallback(new ItemSelectedAction(this, dropDown->options[i].first)); - AddComponent(tempButton); + messagePanel->AddChild(tempButton); currentY += 16; } + + messagePanel->InnerSize = ui::Point(messagePanel->Size.X, currentY); + + if (currentY < messagePanel->Size.Y) + messagePanel->Size.Y = currentY; + Size.Y = messagePanel->Size.Y + 12; } virtual void OnDraw() { diff --git a/src/gui/preview/PreviewController.cpp b/src/gui/preview/PreviewController.cpp index 7ecc8d7a7..e2f9e56e0 100644 --- a/src/gui/preview/PreviewController.cpp +++ b/src/gui/preview/PreviewController.cpp @@ -17,7 +17,7 @@ PreviewController::PreviewController(int saveID, int saveDate, bool instant, Con HasExited(false) { previewModel = new PreviewModel(); - previewView = new PreviewView(); + previewView = new PreviewView(saveID); previewModel->AddObserver(previewView); previewView->AttachController(this); previewModel->SetDoOpen(instant); @@ -42,7 +42,7 @@ PreviewController::PreviewController(int saveID, bool instant, ControllerCallbac HasExited(false) { previewModel = new PreviewModel(); - previewView = new PreviewView(); + previewView = new PreviewView(saveID); previewModel->AddObserver(previewView); previewView->AttachController(this); diff --git a/src/gui/preview/PreviewView.cpp b/src/gui/preview/PreviewView.cpp index c13f50415..f3293d16f 100644 --- a/src/gui/preview/PreviewView.cpp +++ b/src/gui/preview/PreviewView.cpp @@ -18,6 +18,8 @@ #include "gui/interface/Keys.h" #include "gui/dialogues/ErrorMessage.h" +#include "gui/coin/Promote.h" + class PreviewView::LoginAction: public ui::ButtonAction { PreviewView * v; @@ -65,7 +67,7 @@ public: } }; -PreviewView::PreviewView(): +PreviewView::PreviewView(int saveID): ui::Window(ui::Point(-1, -1), ui::Point((XRES/2)+210, (YRES/2)+150)), savePreview(NULL), submitCommentButton(NULL), @@ -128,6 +130,22 @@ PreviewView::PreviewView(): reportButton->Enabled = Client::Ref().GetAuthUser().UserID?true:false; AddComponent(reportButton); + class PromoteAction: public ui::ButtonAction + { + int saveID; + public: + PromoteAction(int saveID) { this->saveID = saveID; } + virtual void ActionCallback(ui::Button * sender) + { + new Promote(saveID); + } + }; + promoteButton = new ui::Button(ui::Point(150, Size.Y - 19), ui::Point((XRES/2)-107 - 149, 19), "Promote"); + promoteButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle; + promoteButton->Enabled = Client::Ref().GetAuthUser().UserID ? true : false; + promoteButton->SetActionCallback(new PromoteAction(saveID)); + AddComponent(promoteButton); + class OpenAction: public ui::ButtonAction { PreviewView * v; diff --git a/src/gui/preview/PreviewView.h b/src/gui/preview/PreviewView.h index 4a68cea50..32a03900f 100644 --- a/src/gui/preview/PreviewView.h +++ b/src/gui/preview/PreviewView.h @@ -33,6 +33,7 @@ class PreviewView: public ui::Window { ui::Button * browserOpenButton; ui::Button * favButton; ui::Button * reportButton; + ui::Button * promoteButton; ui::Button * submitCommentButton; ui::Textbox * addCommentBox; ui::Label * commentWarningLabel; @@ -73,7 +74,7 @@ class PreviewView: public ui::Window { void CheckComment(); public: void AttachController(PreviewController * controller); - PreviewView(); + PreviewView(int saveID); void NotifySaveChanged(PreviewModel * sender); void NotifyCommentsChanged(PreviewModel * sender); void NotifyCommentsPageChanged(PreviewModel * sender); diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index 93ec42734..b5795beca 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -21,6 +21,11 @@ #include "simulation/Simulation.h" +bool CheckUnlockedLegacy(int ID) +{ + return ID >= 0 && ID < PT_NUM && luacon_sim->elements[ID].Unlocked; +} + #ifndef FFI int luacon_partread(lua_State* l) { @@ -82,7 +87,12 @@ int luacon_partwrite(lua_State* l) *((float*)(((unsigned char*)&luacon_sim->parts[i])+offset)) = luaL_optnumber(l, 3, 0); break; case CommandInterface::FormatElement: - luacon_sim->part_change_type(i, luacon_sim->parts[i].x, luacon_sim->parts[i].y, luaL_optinteger(l, 3, 0)); + { + int type = luaL_optinteger(l, 3, 0); + if (!CheckUnlockedLegacy(type)) + return luaL_error(l, "Invalid element id '%d'", type); + luacon_sim->part_change_type(i, luacon_sim->parts[i].x, luacon_sim->parts[i].y, type); + } default: break; } @@ -863,6 +873,8 @@ int luatpt_create(lua_State* l) if ((t = luacon_sim->GetParticleType(std::string(name))) == -1) return luaL_error(l,"Unrecognised element '%s'", name); } + if (!CheckUnlockedLegacy(t)) + return luaL_error(l, "Invalid element id '%d'", t); retid = luacon_sim->create_part(-1, x, y, t); // failing to create a particle often happens (e.g. if space is already occupied) and isn't usually important, so don't raise an error lua_pushinteger(l, retid); @@ -1127,7 +1139,11 @@ int luatpt_set_property(lua_State* l) if (nx >= x && nx < x+w && ny >= y && ny < y+h && (!partsel || partsel == parts[i].type)) { if (format == CommandInterface::FormatElement) + { + if (!CheckUnlockedLegacy(t)) + return luaL_error(l, "Invalid element id '%d'", t); luacon_sim->part_change_type(i, nx, ny, t); + } else if(format == CommandInterface::FormatFloat) *((float*)(((unsigned char*)&luacon_sim->parts[i])+offset)) = f; else @@ -1160,7 +1176,11 @@ int luatpt_set_property(lua_State* l) return 0; if (format == CommandInterface::FormatElement) + { + if (!CheckUnlockedLegacy(t)) + return luaL_error(l, "Invalid element id '%d'", t); luacon_sim->part_change_type(i, luacon_sim->parts[i].x, luacon_sim->parts[i].y, t); + } else if (format == CommandInterface::FormatFloat) *((float*)(((unsigned char*)&luacon_sim->parts[i])+offset)) = f; else diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index 604850e8b..afa995cbb 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -401,13 +401,25 @@ int LuaScriptInterface::tpt_index(lua_State *l) return lua_rawget(l, 1), 1; } +bool CheckUnlocked(int ID) +{ + return ID >= 0 && ID < PT_NUM && luacon_sim->elements[ID].Unlocked; +} + +bool CheckUnlocked(std::string identifier, int ID) +{ + if (identifier.find("DEFAULT_PT_") == 0) + return CheckUnlocked(ID); + return true; +} + int LuaScriptInterface::tpt_newIndex(lua_State *l) { std::string key = luaL_checkstring(l, 2); if (!key.compare("selectedl")) { Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); - if (t) + if (t && CheckUnlocked(t->GetIdentifier(), t->GetToolID())) c->SetActiveTool(0, t); else luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); @@ -415,7 +427,7 @@ int LuaScriptInterface::tpt_newIndex(lua_State *l) else if (!key.compare("selectedr")) { Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); - if (t) + if (t && CheckUnlocked(t->GetIdentifier(), t->GetToolID())) c->SetActiveTool(1, t); else luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); @@ -423,7 +435,7 @@ int LuaScriptInterface::tpt_newIndex(lua_State *l) else if (!key.compare("selecteda")) { Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); - if (t) + if (t && CheckUnlocked(t->GetIdentifier(), t->GetToolID())) c->SetActiveTool(2, t); else luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); @@ -431,7 +443,7 @@ int LuaScriptInterface::tpt_newIndex(lua_State *l) else if (!key.compare("selectedreplace")) { Tool *t = m->GetToolFromIdentifier(luaL_checkstring(l, 3)); - if( t) + if (t && CheckUnlocked(t->GetIdentifier(), t->GetToolID())) c->SetActiveTool(3, t); else luaL_error(l, "Invalid tool identifier: %s", lua_tostring(l, 3)); @@ -914,6 +926,9 @@ int LuaScriptInterface::simulation_partChangeType(lua_State * l) int partIndex = lua_tointeger(l, 1); if(partIndex < 0 || partIndex >= NPART || !luacon_sim->parts[partIndex].type) return 0; + int t = lua_tointeger(l, 2); + if (!CheckUnlocked(t)) + return luaL_error(l, "Invalid element id '%d'", t); luacon_sim->part_change_type(partIndex, luacon_sim->parts[partIndex].x+0.5f, luacon_sim->parts[partIndex].y+0.5f, lua_tointeger(l, 2)); return 0; } @@ -938,6 +953,8 @@ int LuaScriptInterface::simulation_partCreate(lua_State * l) v = ID(type); type = TYP(type); } + if (!CheckUnlocked(type)) + return luaL_error(l, "Invalid element id '%d'", type); lua_pushinteger(l, luacon_sim->create_part(newID, lua_tointeger(l, 2), lua_tointeger(l, 3), type, v)); return 1; } @@ -1039,6 +1056,8 @@ int LuaScriptInterface::simulation_partProperty(lua_State * l) switch(property->Type) { case StructProperty::ParticleType: + if (!CheckUnlocked(lua_tointeger(l, 3))) + return luaL_error(l, "Invalid element id '%d'", lua_tointeger(l, 3)); case StructProperty::Integer: *((int*)propertyAddress) = lua_tointeger(l, 3); break; @@ -1311,6 +1330,9 @@ int LuaScriptInterface::simulation_createParts(lua_State * l) int brush = luaL_optint(l,6,CIRCLE_BRUSH); int flags = luaL_optint(l,7,luacon_sim->replaceModeFlags); + if (!CheckUnlocked(c)) + return luaL_error(l, "Invalid element id '%d'", c); + vector brushList = luacon_model->GetBrushList(); if (brush < 0 || brush >= (int)brushList.size()) return luaL_error(l, "Invalid brush id '%d'", brush); @@ -1335,6 +1357,9 @@ int LuaScriptInterface::simulation_createLine(lua_State * l) int brush = luaL_optint(l,8,CIRCLE_BRUSH); int flags = luaL_optint(l,9,luacon_sim->replaceModeFlags); + if (!CheckUnlocked(c)) + return luaL_error(l, "Invalid element id '%d'", c); + vector brushList = luacon_model->GetBrushList(); if (brush < 0 || brush >= (int)brushList.size()) return luaL_error(l, "Invalid brush id '%d'", brush); @@ -1355,6 +1380,9 @@ int LuaScriptInterface::simulation_createBox(lua_State * l) int c = luaL_optint(l,5,luacon_model->GetActiveTool(0)->GetToolID()); int flags = luaL_optint(l,6,luacon_sim->replaceModeFlags); + if (!CheckUnlocked(c)) + return luaL_error(l, "Invalid element id '%d'", c); + luacon_sim->CreateBox(x1, y1, x2, y2, c, flags); return 0; } @@ -1364,6 +1392,8 @@ int LuaScriptInterface::simulation_floodParts(lua_State * l) int x = luaL_optint(l,1,-1); int y = luaL_optint(l,2,-1); int c = luaL_optint(l,3,luacon_model->GetActiveTool(0)->GetToolID()); + if (!CheckUnlocked(c)) + return luaL_error(l, "Invalid element id '%d'", c); int cm = luaL_optint(l,4,-1); int flags = luaL_optint(l,5,luacon_sim->replaceModeFlags); int ret = luacon_sim->FloodParts(x, y, c, cm, flags); @@ -2533,9 +2563,6 @@ int LuaScriptInterface::elements_allocate(lua_State * l) if (!luacon_sim->elements[i].Enabled) { newID = i; - luacon_sim->elements[i] = Element(); - luacon_sim->elements[i].Enabled = true; - luacon_sim->elements[i].Identifier = strdup(identifier.c_str()); break; } } @@ -2547,9 +2574,6 @@ int LuaScriptInterface::elements_allocate(lua_State * l) if (!luacon_sim->elements[i].Enabled) { newID = i; - luacon_sim->elements[i] = Element(); - luacon_sim->elements[i].Enabled = true; - luacon_sim->elements[i].Identifier = strdup(identifier.c_str()); break; } } @@ -2557,6 +2581,10 @@ int LuaScriptInterface::elements_allocate(lua_State * l) if (newID != -1) { + luacon_sim->elements[newID] = Element(); + luacon_sim->elements[newID].Enabled = true; + luacon_sim->elements[newID].Unlocked = true; + luacon_sim->elements[newID].Identifier = strdup(identifier.c_str()); lua_getglobal(l, "elements"); lua_pushinteger(l, newID); lua_setfield(l, -2, identifier.c_str()); diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 5eccce660..0d3fa0f24 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -353,6 +353,16 @@ GameSave * Simulation::Save(int fullX, int fullY, int fullX2, int fullY2, bool i Particle tempPart = parts[i]; tempPart.x -= blockX*CELL; tempPart.y -= blockY*CELL; + + if (!elements[tempPart.type].Unlocked) + continue; + if (GameSave::TypeInCtype(tempPart.type, tempPart.ctype) && !elements[tempPart.ctype].Unlocked) + tempPart.ctype = 0; + if (GameSave::TypeInTmp(tempPart.type) && !elements[TYP(tempPart.tmp)].Unlocked) + tempPart.tmp = 0; + if (GameSave::TypeInTmp2(tempPart.type, tempPart.tmp2) && !elements[tempPart.tmp2].Unlocked) + tempPart.tmp2 = 0; + if (elements[tempPart.type].Enabled) { if (tempPart.type == PT_SOAP) @@ -4890,15 +4900,15 @@ int Simulation::GetParticleType(std::string type) char * txt = (char*)type.c_str(); // alternative names for some elements - if (!strcasecmp(txt, "C4")) + if (!strcasecmp(txt, "C4") && elements[PT_PLEX].Unlocked) return PT_PLEX; - else if (!strcasecmp(txt, "C5")) + else if (!strcasecmp(txt, "C5") && elements[PT_C5].Unlocked) return PT_C5; - else if (!strcasecmp(txt, "NONE")) + else if (!strcasecmp(txt, "NONE") && elements[PT_NONE].Unlocked) return PT_NONE; for (int i = 1; i < PT_NUM; i++) { - if (!strcasecmp(txt, elements[i].Name) && strlen(elements[i].Name) && elements[i].Enabled) + if (!strcasecmp(txt, elements[i].Name) && strlen(elements[i].Name) && elements[i].Enabled && elements[i].Unlocked) { return i; } diff --git a/src/simulation/elements/ANAR.cpp b/src/simulation/elements/ANAR.cpp index 9c4b4c01d..2bc39a2ee 100644 --- a/src/simulation/elements/ANAR.cpp +++ b/src/simulation/elements/ANAR.cpp @@ -8,6 +8,7 @@ Element_ANAR::Element_ANAR() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = -0.7f; AirDrag = -0.02f * CFDS; diff --git a/src/simulation/elements/BCLN.cpp b/src/simulation/elements/BCLN.cpp index 8fc59b50b..add1c964e 100644 --- a/src/simulation/elements/BCLN.cpp +++ b/src/simulation/elements/BCLN.cpp @@ -8,6 +8,7 @@ Element_BCLN::Element_BCLN() MenuVisible = 1; MenuSection = SC_SPECIAL; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/BMTL.cpp b/src/simulation/elements/BMTL.cpp index 551816483..1fc37db39 100644 --- a/src/simulation/elements/BMTL.cpp +++ b/src/simulation/elements/BMTL.cpp @@ -8,6 +8,7 @@ Element_BMTL::Element_BMTL() MenuVisible = 1; MenuSection = SC_SOLIDS; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/BOMB.cpp b/src/simulation/elements/BOMB.cpp index 93c7b8b80..121771082 100644 --- a/src/simulation/elements/BOMB.cpp +++ b/src/simulation/elements/BOMB.cpp @@ -8,6 +8,7 @@ Element_BOMB::Element_BOMB() MenuVisible = 1; MenuSection = SC_EXPLOSIVE; Enabled = 1; + Unlocked = 1; Advection = 0.6f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/BRMT.cpp b/src/simulation/elements/BRMT.cpp index 46ee6d91b..d54ff2934 100644 --- a/src/simulation/elements/BRMT.cpp +++ b/src/simulation/elements/BRMT.cpp @@ -8,6 +8,7 @@ Element_BRMT::Element_BRMT() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.4f; AirDrag = 0.04f * CFDS; diff --git a/src/simulation/elements/BTRY.cpp b/src/simulation/elements/BTRY.cpp index 62b81c3a0..add71047a 100644 --- a/src/simulation/elements/BTRY.cpp +++ b/src/simulation/elements/BTRY.cpp @@ -8,6 +8,7 @@ Element_BTRY::Element_BTRY() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/CLNE.cpp b/src/simulation/elements/CLNE.cpp index 7f74bd877..92dae0b9f 100644 --- a/src/simulation/elements/CLNE.cpp +++ b/src/simulation/elements/CLNE.cpp @@ -8,6 +8,7 @@ Element_CLNE::Element_CLNE() MenuVisible = 1; MenuSection = SC_SPECIAL; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/DEUT.cpp b/src/simulation/elements/DEUT.cpp index cc9b97b98..20519a2e3 100644 --- a/src/simulation/elements/DEUT.cpp +++ b/src/simulation/elements/DEUT.cpp @@ -8,6 +8,7 @@ Element_DEUT::Element_DEUT() MenuVisible = 1; MenuSection = SC_NUCLEAR; Enabled = 1; + Unlocked = 1; Advection = 0.6f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/DMG.cpp b/src/simulation/elements/DMG.cpp index 47c8c7953..0c22b545c 100644 --- a/src/simulation/elements/DMG.cpp +++ b/src/simulation/elements/DMG.cpp @@ -8,6 +8,7 @@ Element_DMG::Element_DMG() MenuVisible = 1; MenuSection = SC_FORCE; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/DSTW.cpp b/src/simulation/elements/DSTW.cpp index 29efda55c..d6d2cbff0 100644 --- a/src/simulation/elements/DSTW.cpp +++ b/src/simulation/elements/DSTW.cpp @@ -8,6 +8,7 @@ Element_DSTW::Element_DSTW() MenuVisible = 1; MenuSection = SC_LIQUID; Enabled = 1; + Unlocked = 1; Advection = 0.6f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/DUST.cpp b/src/simulation/elements/DUST.cpp index 78bee8e72..78a7ce1a4 100644 --- a/src/simulation/elements/DUST.cpp +++ b/src/simulation/elements/DUST.cpp @@ -8,6 +8,7 @@ Element_DUST::Element_DUST() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.7f; AirDrag = 0.02f * CFDS; diff --git a/src/simulation/elements/ELEC.cpp b/src/simulation/elements/ELEC.cpp index 85af13b4c..1627fb56c 100644 --- a/src/simulation/elements/ELEC.cpp +++ b/src/simulation/elements/ELEC.cpp @@ -8,6 +8,7 @@ Element_ELEC::Element_ELEC() MenuVisible = 1; MenuSection = SC_NUCLEAR; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/Element.cpp b/src/simulation/elements/Element.cpp index 42ee959ec..519a0a31b 100644 --- a/src/simulation/elements/Element.cpp +++ b/src/simulation/elements/Element.cpp @@ -8,6 +8,8 @@ Element::Element(): MenuVisible(0), MenuSection(0), Enabled(0), + Unlocked(0), + UnlockPrice(20), Advection(0.0f), AirDrag(-0.0f * CFDS), diff --git a/src/simulation/elements/Element.h b/src/simulation/elements/Element.h index f726d410f..28210a17e 100644 --- a/src/simulation/elements/Element.h +++ b/src/simulation/elements/Element.h @@ -19,6 +19,8 @@ public: int MenuVisible; int MenuSection; int Enabled; + int Unlocked; + int UnlockPrice; float Advection; float AirDrag; diff --git a/src/simulation/elements/FIGH.cpp b/src/simulation/elements/FIGH.cpp index 82fda3890..479b8d74e 100644 --- a/src/simulation/elements/FIGH.cpp +++ b/src/simulation/elements/FIGH.cpp @@ -8,6 +8,7 @@ Element_FIGH::Element_FIGH() MenuVisible = 1; MenuSection = SC_SPECIAL; Enabled = 1; + UnlockPrice = 5000; Advection = 0.5f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/FIRE.cpp b/src/simulation/elements/FIRE.cpp index baead09f8..783ce6445 100644 --- a/src/simulation/elements/FIRE.cpp +++ b/src/simulation/elements/FIRE.cpp @@ -10,6 +10,7 @@ Element_FIRE::Element_FIRE() MenuVisible = 1; MenuSection = SC_EXPLOSIVE; Enabled = 1; + Unlocked = 1; Advection = 0.9f; AirDrag = 0.04f * CFDS; diff --git a/src/simulation/elements/FIRW.cpp b/src/simulation/elements/FIRW.cpp index 82206c516..973295d01 100644 --- a/src/simulation/elements/FIRW.cpp +++ b/src/simulation/elements/FIRW.cpp @@ -12,6 +12,7 @@ Element_FIRW::Element_FIRW() MenuVisible = 1; MenuSection = SC_EXPLOSIVE; Enabled = 1; + Unlocked = 1; Advection = 0.2f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/GAS.cpp b/src/simulation/elements/GAS.cpp index 01a039455..6e5a1e3ac 100644 --- a/src/simulation/elements/GAS.cpp +++ b/src/simulation/elements/GAS.cpp @@ -8,6 +8,7 @@ Element_GAS::Element_GAS() MenuVisible = 1; MenuSection = SC_GAS; Enabled = 1; + Unlocked = 1; Advection = 1.0f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/GOO.cpp b/src/simulation/elements/GOO.cpp index 0fbc7681d..74af9d07f 100644 --- a/src/simulation/elements/GOO.cpp +++ b/src/simulation/elements/GOO.cpp @@ -8,6 +8,7 @@ Element_GOO::Element_GOO() MenuVisible = 1; MenuSection = SC_SOLIDS; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/GRAV.cpp b/src/simulation/elements/GRAV.cpp index 6a016a690..adf283f9b 100644 --- a/src/simulation/elements/GRAV.cpp +++ b/src/simulation/elements/GRAV.cpp @@ -10,6 +10,7 @@ Element_GRAV::Element_GRAV() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.7f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/GUNP.cpp b/src/simulation/elements/GUNP.cpp index 5232c2763..afecdca82 100644 --- a/src/simulation/elements/GUNP.cpp +++ b/src/simulation/elements/GUNP.cpp @@ -8,6 +8,7 @@ Element_GUNP::Element_GUNP() MenuVisible = 1; MenuSection = SC_EXPLOSIVE; Enabled = 1; + Unlocked = 1; Advection = 0.7f; AirDrag = 0.02f * CFDS; diff --git a/src/simulation/elements/H2.cpp b/src/simulation/elements/H2.cpp index 090da2d08..df744cff4 100644 --- a/src/simulation/elements/H2.cpp +++ b/src/simulation/elements/H2.cpp @@ -8,6 +8,7 @@ Element_H2::Element_H2() MenuVisible = 1; MenuSection = SC_GAS; Enabled = 1; + Unlocked = 1; Advection = 2.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/ICEI.cpp b/src/simulation/elements/ICEI.cpp index b54a836a0..3c41345bb 100644 --- a/src/simulation/elements/ICEI.cpp +++ b/src/simulation/elements/ICEI.cpp @@ -8,6 +8,7 @@ Element_ICEI::Element_ICEI() MenuVisible = 1; MenuSection = SC_SOLIDS; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/INSL.cpp b/src/simulation/elements/INSL.cpp index 8469ca073..7c66e660c 100644 --- a/src/simulation/elements/INSL.cpp +++ b/src/simulation/elements/INSL.cpp @@ -8,6 +8,7 @@ Element_INSL::Element_INSL() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/LAVA.cpp b/src/simulation/elements/LAVA.cpp index 04d282374..16f4077b5 100644 --- a/src/simulation/elements/LAVA.cpp +++ b/src/simulation/elements/LAVA.cpp @@ -8,6 +8,7 @@ Element_LAVA::Element_LAVA() MenuVisible = 1; MenuSection = SC_LIQUID; Enabled = 1; + Unlocked = 1; Advection = 0.3f; AirDrag = 0.02f * CFDS; diff --git a/src/simulation/elements/LIGH.cpp b/src/simulation/elements/LIGH.cpp index e7b2df96f..5be436466 100644 --- a/src/simulation/elements/LIGH.cpp +++ b/src/simulation/elements/LIGH.cpp @@ -9,6 +9,7 @@ Element_LIGH::Element_LIGH() MenuVisible = 1; MenuSection = SC_EXPLOSIVE; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/METL.cpp b/src/simulation/elements/METL.cpp index de59cbfd6..633fad3de 100644 --- a/src/simulation/elements/METL.cpp +++ b/src/simulation/elements/METL.cpp @@ -8,6 +8,7 @@ Element_METL::Element_METL() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/NEUT.cpp b/src/simulation/elements/NEUT.cpp index 67f48bca4..02c1e7c3c 100644 --- a/src/simulation/elements/NEUT.cpp +++ b/src/simulation/elements/NEUT.cpp @@ -8,6 +8,7 @@ Element_NEUT::Element_NEUT() MenuVisible = 1; MenuSection = SC_NUCLEAR; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/NSCN.cpp b/src/simulation/elements/NSCN.cpp index cbe056c2d..e42ac31a2 100644 --- a/src/simulation/elements/NSCN.cpp +++ b/src/simulation/elements/NSCN.cpp @@ -8,6 +8,7 @@ Element_NSCN::Element_NSCN() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/O2.cpp b/src/simulation/elements/O2.cpp index a6e54c0a7..6a2ed01d0 100644 --- a/src/simulation/elements/O2.cpp +++ b/src/simulation/elements/O2.cpp @@ -8,6 +8,7 @@ Element_O2::Element_O2() MenuVisible = 1; MenuSection = SC_GAS; Enabled = 1; + Unlocked = 1; Advection = 2.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/OIL.cpp b/src/simulation/elements/OIL.cpp index 6f2327a00..530fd6827 100644 --- a/src/simulation/elements/OIL.cpp +++ b/src/simulation/elements/OIL.cpp @@ -8,6 +8,7 @@ Element_OIL::Element_OIL() MenuVisible = 1; MenuSection = SC_LIQUID; Enabled = 1; + Unlocked = 1; Advection = 0.6f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/PBCN.cpp b/src/simulation/elements/PBCN.cpp index 2c4cec28b..54e0f7ba5 100644 --- a/src/simulation/elements/PBCN.cpp +++ b/src/simulation/elements/PBCN.cpp @@ -8,6 +8,7 @@ Element_PBCN::Element_PBCN() MenuVisible = 1; MenuSection = SC_POWERED; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/PCLN.cpp b/src/simulation/elements/PCLN.cpp index 7fe7fba91..2041f406a 100644 --- a/src/simulation/elements/PCLN.cpp +++ b/src/simulation/elements/PCLN.cpp @@ -8,6 +8,7 @@ Element_PCLN::Element_PCLN() MenuVisible = 1; MenuSection = SC_POWERED; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/PHOT.cpp b/src/simulation/elements/PHOT.cpp index 17c65d02b..b2144fee1 100644 --- a/src/simulation/elements/PHOT.cpp +++ b/src/simulation/elements/PHOT.cpp @@ -8,6 +8,7 @@ Element_PHOT::Element_PHOT() MenuVisible = 1; MenuSection = SC_NUCLEAR; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/PIPE.cpp b/src/simulation/elements/PIPE.cpp index 3bc8e6709..c47157009 100644 --- a/src/simulation/elements/PIPE.cpp +++ b/src/simulation/elements/PIPE.cpp @@ -11,6 +11,7 @@ Element_PIPE::Element_PIPE() MenuVisible = 1; MenuSection = SC_FORCE; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/PLEX.cpp b/src/simulation/elements/PLEX.cpp index 0a1fa9809..8f349a7ff 100644 --- a/src/simulation/elements/PLEX.cpp +++ b/src/simulation/elements/PLEX.cpp @@ -8,6 +8,7 @@ Element_PLEX::Element_PLEX() MenuVisible = 1; MenuSection = SC_EXPLOSIVE; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/PLNT.cpp b/src/simulation/elements/PLNT.cpp index a67086682..740ce8407 100644 --- a/src/simulation/elements/PLNT.cpp +++ b/src/simulation/elements/PLNT.cpp @@ -10,6 +10,7 @@ Element_PLNT::Element_PLNT() MenuVisible = 1; MenuSection = SC_SOLIDS; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/PLUT.cpp b/src/simulation/elements/PLUT.cpp index dd0829d94..621c67fe5 100644 --- a/src/simulation/elements/PLUT.cpp +++ b/src/simulation/elements/PLUT.cpp @@ -8,6 +8,7 @@ Element_PLUT::Element_PLUT() MenuVisible = 1; MenuSection = SC_NUCLEAR; Enabled = 1; + Unlocked = 1; Advection = 0.4f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/POLO.cpp b/src/simulation/elements/POLO.cpp index 368a29326..cfa7bc2d0 100644 --- a/src/simulation/elements/POLO.cpp +++ b/src/simulation/elements/POLO.cpp @@ -8,6 +8,7 @@ Element_POLO::Element_POLO() MenuVisible = 1; MenuSection = SC_NUCLEAR; Enabled = 1; + Unlocked = 1; Advection = 0.4f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/PSCN.cpp b/src/simulation/elements/PSCN.cpp index 750c1536c..381c57511 100644 --- a/src/simulation/elements/PSCN.cpp +++ b/src/simulation/elements/PSCN.cpp @@ -8,6 +8,7 @@ Element_PSCN::Element_PSCN() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/SALT.cpp b/src/simulation/elements/SALT.cpp index 98bbfa592..8242dbd60 100644 --- a/src/simulation/elements/SALT.cpp +++ b/src/simulation/elements/SALT.cpp @@ -8,6 +8,7 @@ Element_SALT::Element_SALT() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.4f; AirDrag = 0.04f * CFDS; diff --git a/src/simulation/elements/SAND.cpp b/src/simulation/elements/SAND.cpp index 0a9419605..426ad9899 100644 --- a/src/simulation/elements/SAND.cpp +++ b/src/simulation/elements/SAND.cpp @@ -8,6 +8,7 @@ Element_SAND::Element_SAND() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.4f; AirDrag = 0.04f * CFDS; diff --git a/src/simulation/elements/SAWD.cpp b/src/simulation/elements/SAWD.cpp index 77ae46e77..89f84baba 100644 --- a/src/simulation/elements/SAWD.cpp +++ b/src/simulation/elements/SAWD.cpp @@ -8,6 +8,7 @@ Element_SAWD::Element_SAWD() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.7f; AirDrag = 0.02f * CFDS; diff --git a/src/simulation/elements/SLTW.cpp b/src/simulation/elements/SLTW.cpp index 01ce8b42f..f3f224ea2 100644 --- a/src/simulation/elements/SLTW.cpp +++ b/src/simulation/elements/SLTW.cpp @@ -8,6 +8,7 @@ Element_SLTW::Element_SLTW() MenuVisible = 1; MenuSection = SC_LIQUID; Enabled = 1; + Unlocked = 1; Advection = 0.6f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/SMKE.cpp b/src/simulation/elements/SMKE.cpp index 2d0483bc1..844e67e6b 100644 --- a/src/simulation/elements/SMKE.cpp +++ b/src/simulation/elements/SMKE.cpp @@ -8,6 +8,7 @@ Element_SMKE::Element_SMKE() MenuVisible = 1; MenuSection = SC_GAS; Enabled = 1; + Unlocked = 1; Advection = 0.9f; AirDrag = 0.04f * CFDS; diff --git a/src/simulation/elements/SNOW.cpp b/src/simulation/elements/SNOW.cpp index 7c066e829..923268891 100644 --- a/src/simulation/elements/SNOW.cpp +++ b/src/simulation/elements/SNOW.cpp @@ -8,6 +8,7 @@ Element_SNOW::Element_SNOW() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.7f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/SPRK.cpp b/src/simulation/elements/SPRK.cpp index b6c53f25c..25e821ac7 100644 --- a/src/simulation/elements/SPRK.cpp +++ b/src/simulation/elements/SPRK.cpp @@ -8,6 +8,7 @@ Element_SPRK::Element_SPRK() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/STKM.cpp b/src/simulation/elements/STKM.cpp index 8e4a8d93e..0cc00fc09 100644 --- a/src/simulation/elements/STKM.cpp +++ b/src/simulation/elements/STKM.cpp @@ -8,6 +8,7 @@ Element_STKM::Element_STKM() MenuVisible = 1; MenuSection = SC_SPECIAL; Enabled = 1; + UnlockPrice = 2000; Advection = 0.5f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/STKM2.cpp b/src/simulation/elements/STKM2.cpp index 5f1c344ae..f01b0f6ae 100644 --- a/src/simulation/elements/STKM2.cpp +++ b/src/simulation/elements/STKM2.cpp @@ -8,6 +8,7 @@ Element_STKM2::Element_STKM2() MenuVisible = 1; MenuSection = SC_SPECIAL; Enabled = 1; + UnlockPrice = 2000; Advection = 0.5f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/STNE.cpp b/src/simulation/elements/STNE.cpp index 7dbfc7cda..ca1fa64ea 100644 --- a/src/simulation/elements/STNE.cpp +++ b/src/simulation/elements/STNE.cpp @@ -8,6 +8,7 @@ Element_STNE::Element_STNE() MenuVisible = 1; MenuSection = SC_POWDERS; Enabled = 1; + Unlocked = 1; Advection = 0.4f; AirDrag = 0.04f * CFDS; diff --git a/src/simulation/elements/SWCH.cpp b/src/simulation/elements/SWCH.cpp index 4c21b2cef..8d57a3690 100644 --- a/src/simulation/elements/SWCH.cpp +++ b/src/simulation/elements/SWCH.cpp @@ -8,6 +8,7 @@ Element_SWCH::Element_SWCH() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/THDR.cpp b/src/simulation/elements/THDR.cpp index e1aaa5362..90caa8ca9 100644 --- a/src/simulation/elements/THDR.cpp +++ b/src/simulation/elements/THDR.cpp @@ -8,6 +8,7 @@ Element_THDR::Element_THDR() MenuVisible = 1; MenuSection = SC_EXPLOSIVE; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/TRON.cpp b/src/simulation/elements/TRON.cpp index 92a5884dd..61c624716 100644 --- a/src/simulation/elements/TRON.cpp +++ b/src/simulation/elements/TRON.cpp @@ -8,6 +8,7 @@ Element_TRON::Element_TRON() MenuVisible = 1; MenuSection = SC_SPECIAL; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/URAN.cpp b/src/simulation/elements/URAN.cpp index cf7c59acb..b4a2c9daa 100644 --- a/src/simulation/elements/URAN.cpp +++ b/src/simulation/elements/URAN.cpp @@ -8,6 +8,7 @@ Element_URAN::Element_URAN() MenuVisible = 1; MenuSection = SC_NUCLEAR; Enabled = 1; + Unlocked = 1; Advection = 0.4f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/WATR.cpp b/src/simulation/elements/WATR.cpp index 92d83e42d..56b42d1da 100644 --- a/src/simulation/elements/WATR.cpp +++ b/src/simulation/elements/WATR.cpp @@ -8,6 +8,7 @@ Element_WATR::Element_WATR() MenuVisible = 1; MenuSection = SC_LIQUID; Enabled = 1; + Unlocked = 1; Advection = 0.6f; AirDrag = 0.01f * CFDS; diff --git a/src/simulation/elements/WIFI.cpp b/src/simulation/elements/WIFI.cpp index c3ab4d106..d0c53625f 100644 --- a/src/simulation/elements/WIFI.cpp +++ b/src/simulation/elements/WIFI.cpp @@ -8,6 +8,7 @@ Element_WIFI::Element_WIFI() MenuVisible = 1; MenuSection = SC_ELEC; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/WOOD.cpp b/src/simulation/elements/WOOD.cpp index 5e179ffe3..8df1dde9c 100644 --- a/src/simulation/elements/WOOD.cpp +++ b/src/simulation/elements/WOOD.cpp @@ -10,6 +10,7 @@ Element_WOOD::Element_WOOD() MenuVisible = 1; MenuSection = SC_SOLIDS; Enabled = 1; + Unlocked = 1; Advection = 0.0f; AirDrag = 0.00f * CFDS; diff --git a/src/simulation/elements/WTRV.cpp b/src/simulation/elements/WTRV.cpp index f0152de66..fa6ac7356 100644 --- a/src/simulation/elements/WTRV.cpp +++ b/src/simulation/elements/WTRV.cpp @@ -8,6 +8,7 @@ Element_WTRV::Element_WTRV() MenuVisible = 1; MenuSection = SC_GAS; Enabled = 1; + Unlocked = 1; Advection = 1.0f; AirDrag = 0.01f * CFDS;