Downloads containing STVutil.asc

Downloads
Name Author Game Mode Rating
TSF with JJ2+ Only: Custom HUD Spaz Electro Mutator N/A Download file

File preview

  1. funcdef void TimerVDictionaryFunction(dictionary @);
  2. class TimerV : jjBEHAVIORINTERFACE
  3. {
  4.         TimerV(int time, jjVOIDFUNC @callback)
  5.         {
  6.                 @_callback = @callback;
  7.                 _start(time);
  8.         }
  9.         TimerV(int time, TimerVDictionaryFunction @callback, dictionary @arguments)
  10.         {
  11.                 @_callbackWithArguments = @callback;
  12.                 @_arguments = @arguments;
  13.                 _start(time);
  14.         }
  15.         bool get_Active() const
  16.         {
  17.                 return cast<jjBEHAVIORINTERFACE @>(_object.behavior) is this;
  18.         }
  19.         int get_Elapsed() const
  20.         {
  21.                 if (Active)
  22.                         return _object.age;
  23.                 return -1;
  24.         }
  25.         int get_Total() const
  26.         {
  27.                 if (Active)
  28.                         return _object.counter;
  29.                 return -1;
  30.         }
  31.         int get_Remaining() const
  32.         {
  33.                 if (Active)
  34.                         return _object.counter - _object.age;
  35.                 return -1;
  36.         }
  37.         bool Stop()
  38.         {
  39.                 if (Active && _object.age < _object.counter)
  40.                 {
  41.                         _object.delete();
  42.                         return true;
  43.                 }
  44.                 return false;
  45.         }
  46.         bool Paused = false;
  47.  
  48. private
  49.         jjVOIDFUNC @_callback = null;
  50. private
  51.         TimerVDictionaryFunction @_callbackWithArguments;
  52. private
  53.         dictionary @_arguments;
  54. private
  55.         jjOBJ @_object;
  56. private
  57.         int _startTime;
  58. private
  59.         void _start(int time)
  60.         {
  61.                 if (time > 0)
  62.                 {
  63.                         @_object = jjObjects[jjAddObject(OBJECT::BEES, -1000, -1000, 0, CREATOR::OBJECT, BEHAVIOR::BEES)];
  64.                         _object.behavior = this;
  65.                         _object.counter = time;
  66.                         _object.age = 0;
  67.                         _object.playerHandling = HANDLING::PARTICLE;
  68.                         _object.deactivates = false;
  69.                         _startTime = jjGameTicks;
  70.                 }
  71.                 else
  72.                 {
  73.                         @_object = jjObjects[0]; // avoid null pointer access
  74.                         _pickCallback();
  75.                 }
  76.         }
  77. private
  78.         void onBehave(jjOBJ @obj)
  79.         {
  80.                 if (!Paused && jjGameTicks > _startTime && obj is _object && ++_object.age >= _object.counter)
  81.                 {
  82.                         _pickCallback();
  83.                         _object.delete();
  84.                 }
  85.         }
  86. private
  87.         void _pickCallback()
  88.         {
  89.                 if (_callback !is null)
  90.                         _callback();
  91.                 else
  92.                         _callbackWithArguments(_arguments);
  93.         }
  94. }
  95.  
  96. class Key
  97. {
  98.         string id;
  99.         uint code;
  100.  
  101.         Key(string id, uint code)
  102.         {
  103.                 this.id = id;
  104.                 this.code = code;
  105.         }
  106. }
  107.  
  108. jjRNG stvutilRNG = jjRNG();
  109. jjTEXTAPPEARANCE normalTextAppearance = jjTEXTAPPEARANCE(STRING::NORMAL);
  110.  
  111. array<Key @>
  112.         KEYS = {
  113.                 Key("F2", 0x71),                         // 0
  114.                 Key("F5", 0x74),                         // 1
  115.                 Key("F6", 0x75),                         // 2
  116.                 Key("F7", 0x76),                         // 3
  117.                 Key("F10", 0x79),                        // 4
  118.                 Key("F11", 0x7A),                        // 5
  119.                 Key("Insert", 0x2D),             // 6
  120.                 Key("Home", 0x24),                       // 7
  121.                 Key("PageUp", 0x21),             // 8
  122.                 Key("Delete", 0x2E),             // 9
  123.                 Key("End", 0x23),                        // 10
  124.                 Key("PageDown", 0x22),           // 11
  125.                 Key("Colon", 0xBA),                      // 12
  126.                 Key("QuotationMark", 0xDE),      // 13
  127.                 Key("Backspace", 0x08),          // 14
  128.                 Key("Backslash", 0xDC),          // 15
  129.                 Key("Backquote", 0xC0),          // 16
  130.                 Key("BracketLeft", 0xDB),        // 17
  131.                 Key("BracketRight", 0xDD),       // 18
  132.                 Key("Comma", 0xBC),                      // 19
  133.                 Key("Minus", 0xBD),                      // 20
  134.                 Key("Period", 0xBE),             // 21
  135.                 Key("Slash", 0xBF),                      // 22
  136.                 Key("Plus", 0xBB),                       // 23
  137.                 Key("Shift", 0x10),                      // 24
  138.                 Key("Alt", 0x12),                        // 25
  139.                 Key("Control", 0x11),            // 26
  140.                 Key("Tab", 0x09),                        // 27
  141.                 Key("Caps Lock", 0x14),          // 28
  142.                 Key("Space", 0x20),                      // 29
  143.                 Key("Up", 0x26),                         // 30
  144.                 Key("Down", 0x28),                       // 31
  145.                 Key("Left", 0x25),                       // 32
  146.                 Key("Right", 0x27),                      // 33
  147.                 Key("NumpadSlash", 0x6F),        // 34
  148.                 Key("NumpadAsterisk", 0x6A), // 35
  149.                 Key("NumpadMinus", 0x6D),        // 36
  150.                 Key("NumpadPlus", 0x6B),         // 37
  151.                 Key("Numpad1", 0x61),            // 38
  152.                 Key("Numpad2", 0x62),            // 39
  153.                 Key("Numpad3", 0x63),            // 40
  154.                 Key("Numpad4", 0x64),            // 41
  155.                 Key("Numpad5", 0x65),            // 42
  156.                 Key("Numpad6", 0x66),            // 43
  157.                 Key("Numpad7", 0x67),            // 44
  158.                 Key("Numpad8", 0x68),            // 45
  159.                 Key("Numpad9", 0x69),            // 46
  160.                 Key("Numpad0", 0x60),            // 47
  161.                 Key("NumpadPeriod", 0x6E),       // 48
  162.                 Key("0", 0x30),                          // 49
  163.                 Key("1", 0x31),                          // 50
  164.                 Key("2", 0x32),                          // 51
  165.                 Key("3", 0x33),                          // 52
  166.                 Key("4", 0x34),                          // 53
  167.                 Key("5", 0x35),                          // 54
  168.                 Key("6", 0x36),                          // 55
  169.                 Key("7", 0x37),                          // 56
  170.                 Key("8", 0x38),                          // 57
  171.                 Key("9", 0x39),                          // 58
  172.                 Key("A", 0x41),                          // 59
  173.                 Key("B", 0x42),                          // 60
  174.                 Key("C", 0x43),                          // 61
  175.                 Key("D", 0x44),                          // 62
  176.                 Key("E", 0x45),                          // 63
  177.                 Key("F", 0x46),                          // 64
  178.                 Key("G", 0x47),                          // 65
  179.                 Key("H", 0x48),                          // 66
  180.                 Key("I", 0x49),                          // 67
  181.                 Key("J", 0x4A),                          // 68
  182.                 Key("K", 0x4B),                          // 69
  183.                 Key("L", 0x4C),                          // 70
  184.                 Key("M", 0x4D),                          // 71
  185.                 Key("N", 0x4E),                          // 72
  186.                 Key("O", 0x4F),                          // 73
  187.                 Key("P", 0x50),                          // 74
  188.                 Key("Q", 0x51),                          // 75
  189.                 Key("R", 0x52),                          // 76
  190.                 Key("S", 0x53),                          // 77
  191.                 Key("T", 0x54),                          // 78
  192.                 Key("U", 0x55),                          // 79
  193.                 Key("V", 0x56),                          // 80
  194.                 Key("W", 0x57),                          // 81
  195.                 Key("X", 0x58),                          // 82
  196.                 Key("Y", 0x59),                          // 83
  197.                 Key("Z", 0x5A),                          // 84
  198.                 Key("Enter", 0x0D),                      // 85
  199. };
  200.  
  201. class AnimatedSprite
  202. {
  203.         int id;
  204.         float frame;
  205.         int frame_count;
  206.         int x;
  207.         int y;
  208.         double anim_speed;
  209.         bool can_reverse;
  210.         bool reverse = false;
  211.         bool visible = true;
  212.         ANIM::Set animSet = ANIM::AMMO;
  213.         SPRITE::Mode spriteMode = SPRITE::NORMAL;
  214.         int spriteModeParam = 123;
  215.         SPRITE::Direction direction = SPRITE::FLIPNONE;
  216.  
  217.         AnimatedSprite(int id, int frame, int x, int y, double anim_speed, bool can_reverse)
  218.         {
  219.                 this.id = id;
  220.                 this.frame = frame;
  221.                 this.x = x;
  222.                 this.y = y;
  223.                 this.anim_speed = anim_speed;
  224.                 this.can_reverse = can_reverse;
  225.                 this.frame_count = jjAnimations[jjAnimSets[animSet].firstAnim + id].frameCount;
  226.         }
  227.  
  228.         void setVisible(bool visible)
  229.         {
  230.                 this.visible = visible;
  231.         }
  232.  
  233.         void setAnimSet(ANIM::Set animSet)
  234.         {
  235.                 this.animSet = animSet;
  236.                 this.frame_count = jjAnimations[jjAnimSets[animSet].firstAnim + id].frameCount;
  237.         }
  238.  
  239.         void setId(uint id)
  240.         {
  241.                 this.id = id;
  242.                 this.frame_count = jjAnimations[jjAnimSets[this.animSet].firstAnim + id].frameCount;
  243.         }
  244.  
  245.         void update()
  246.         {
  247.                 if (this.reverse == false)
  248.                 {
  249.                         this.frame += this.anim_speed;
  250.                 }
  251.                 else
  252.                 {
  253.                         this.frame -= this.anim_speed;
  254.                 }
  255.  
  256.                 if (this.frame > this.frame_count)
  257.                 {
  258.                         if (this.can_reverse == true)
  259.                         {
  260.                                 this.reverse = not this.reverse;
  261.                         }
  262.                         else
  263.                         {
  264.                                 this.frame = 0;
  265.                         }
  266.                 }
  267.  
  268.                 if (this.frame <= 0)
  269.                 {
  270.                         if (this.can_reverse == true)
  271.                         {
  272.                                 this.reverse = not this.reverse;
  273.                         }
  274.                         else
  275.                         {
  276.                                 this.frame = 0;
  277.                         }
  278.                 }
  279.         }
  280.  
  281.         void draw(jjCANVAS @canvas)
  282.         {
  283.                 if (this.visible)
  284.                 {
  285.                         canvas.drawSprite(this.x, this.y, this.animSet, this.id, int(this.frame), this.direction, this.spriteMode, this.spriteModeParam);
  286.                 }
  287.         }
  288. }
  289.  
  290. class Vector2
  291. {
  292.         uint x;
  293.         uint y;
  294.  
  295.         Vector2(int x, int y)
  296.         {
  297.                 this.x = x;
  298.                 this.y = y;
  299.         }
  300.  
  301.         float magnitude(Vector2 @otherVector)
  302.         {
  303.                 return sqrt((this.x + this.y) - (otherVector.x + otherVector.y));
  304.         }
  305. };
  306.  
  307. class Box
  308. {
  309.         uint x;
  310.         uint y;
  311.         uint width;
  312.         uint height;
  313.  
  314.         Box(uint x, uint y, uint width, uint height)
  315.         {
  316.                 this.x = x;
  317.                 this.y = y;
  318.                 this.width = width;
  319.                 this.height = height;
  320.         }
  321.  
  322.         void draw(jjCANVAS @canvas)
  323.         {
  324.                 canvas.drawRectangle(this.x, this.y, this.width, this.height, 0, SPRITE::NORMAL, 0);
  325.         }
  326. }
  327.  
  328. // shouldClose: bool
  329. funcdef bool DialogueChoiceCallback(DialogueChoice @, Dialogue @);
  330. class DialogueChoice
  331. {
  332.         string text;
  333.         int choiceId;
  334.         DialogueChoiceCallback @callback;
  335.  
  336.         DialogueChoice(string text, int choiceId, DialogueChoiceCallback @callback)
  337.         {
  338.                 this.text = text;
  339.                 this.choiceId = choiceId;
  340.                 @ this.callback = callback;
  341.         }
  342.  
  343.         void draw(jjCANVAS @canvas, Box @box, string originalText, bool selected)
  344.         {
  345.                 canvas.drawString(box.x, box.y + 40 + (choiceId * 45) + getStringHeight(originalText), (selected ? "|" : "") + "[" + formatInt(choiceId + 1) + "] " + this.text, STRING::MEDIUM, STRING::NORMAL, 0);
  346.         }
  347. }
  348.  
  349. class Dialogue
  350. {
  351.         string text;
  352.         string textDisplayed;
  353.  
  354.         uint choice;
  355.  
  356.         int speed = 5;
  357.         int x = 0;
  358.         int y = 0;
  359.         int lastCharTick = 0;
  360.  
  361.         bool visible = false;
  362.         bool finished = false;
  363.         bool can_skip = true;
  364.         bool moreDialog = false;
  365.         bool skipped = false;
  366.         bool keyCooldown = false;
  367.         bool characterLoaded = false;
  368.  
  369.         array<DialogueChoice @> choices;
  370.  
  371.         string character;
  372.  
  373.         int characterCID = 0;
  374.         int characterScaleX = 1;
  375.         int characterScaleY = 1;
  376.  
  377.         Box @box;
  378.         Box @characterBox;
  379.  
  380.         Dialogue(string text, array<DialogueChoice @> choices)
  381.         {
  382.                 this.text = text;
  383.                 this.x = 0;
  384.                 this.y = 0;
  385.                 this.choices = choices;
  386.         }
  387.  
  388.         Dialogue(string text, array<DialogueChoice @> choices,
  389.                          string character, int CID, Box @characterBox)
  390.         {
  391.                 this.text = text;
  392.                 this.x = 0;
  393.                 this.y = 0;
  394.                 this.choices = choices;
  395.  
  396.                 this.character = character;
  397.                 this.characterCID = CID;
  398.                 @ this.characterBox = characterBox;
  399.         }
  400.  
  401.         void initialize()
  402.         {
  403.                 @ this.box = Box(0, 0, jjGetStringWidth(this.text, STRING::MEDIUM, normalTextAppearance), 50 + (this.choices.length * 45));
  404.                 this.visible = true;
  405.                 this.finished = false;
  406.                 this.textDisplayed = "";
  407.                 this.lastCharTick = jjGameTicks;
  408.  
  409.                 // (this.box.x) - uint(
  410.                 //      jjAnimFrames[jjAnimations[jjAnimSets[ANIM::CUSTOM[this.characterCID]]]]
  411.                 //              .width / 2.5
  412.                 // ),
  413.                 // jjResolutionHeight / 2,
  414.  
  415.                 jjAnimSets[ANIM::CUSTOM[this.characterCID]].load(jjPIXELMAP(this.character),
  416.                                                                                                                  this.characterBox.width, this.characterBox.height);
  417.  
  418.                 this.characterLoaded = true;
  419.  
  420.                 uint longestChoice = 1;
  421.  
  422.                 for (uint choiceIndex = 0; choiceIndex < this.choices.length; choiceIndex++)
  423.                 {
  424.                         DialogueChoice @choice = this.choices[choiceIndex];
  425.  
  426.                         if (getStringLength(choice.text) > longestChoice)
  427.                                 longestChoice = getStringLength(choice.text);
  428.                 }
  429.  
  430.                 this.box.width += (longestChoice * 45);
  431.         }
  432.  
  433.         void reload()
  434.         {
  435.                 @ this.box = Box(0, 0, jjGetStringWidth(this.text, STRING::MEDIUM, normalTextAppearance), 50 + (this.choices.length * 45));
  436.  
  437.                 jjAnimSets[ANIM::CUSTOM[this.characterCID]].load(jjPIXELMAP(this.character),
  438.                                                                                                                  this.characterBox.width, this.characterBox.height);
  439.  
  440.                 this.characterLoaded = true;
  441.  
  442.                 uint longestChoice = 1;
  443.  
  444.                 for (uint choiceIndex = 0; choiceIndex < this.choices.length; choiceIndex++)
  445.                 {
  446.                         DialogueChoice @choice = this.choices[choiceIndex];
  447.  
  448.                         if (getStringLength(choice.text) > longestChoice)
  449.                                 longestChoice = getStringLength(choice.text);
  450.                 }
  451.  
  452.                 this.box.width += (longestChoice * 45);
  453.         }
  454.  
  455.         void loadNewCharacter(string character, int CID, Box @characterBox)
  456.         {
  457.                 this.character = character;
  458.                 this.characterCID = CID;
  459.                 @ this.characterBox = characterBox;
  460.  
  461.                 jjAnimSets[ANIM::CUSTOM[CID]].load(jjPIXELMAP(character),
  462.                                                                                    characterBox.width, characterBox.height);
  463.         }
  464.  
  465.         void draw(jjCANVAS @canvas)
  466.         {
  467.                 if (this.visible)
  468.                 {
  469.                         this.box.x = jjResolutionWidth / 2 - (jjGetStringWidth(this.text, STRING::MEDIUM, normalTextAppearance)) / 2 + this.x;
  470.                         this.box.y = (jjResolutionHeight - 100 + this.y) - 25 - (this.choices.length * 25);
  471.                         this.box.draw(canvas);
  472.  
  473.                         canvas.drawString(
  474.                                 this.box.x,
  475.                                 this.box.y + 10,
  476.                                 this.textDisplayed, STRING::MEDIUM, STRING::NORMAL, 0);
  477.  
  478.                         if (this.finished)
  479.                         {
  480.                                 for (uint choiceIndex = 0; choiceIndex < this.choices.length; choiceIndex++)
  481.                                 {
  482.                                         DialogueChoice @choice = this.choices[choiceIndex];
  483.  
  484.                                         choice.draw(
  485.                                                 canvas,
  486.                                                 @ this.box,
  487.                                                 this.text,
  488.                                                 this.choice ==
  489.                                                         choiceIndex);
  490.                                 }
  491.                         }
  492.  
  493.                         if (this.moreDialog)
  494.                         {
  495.                                 canvas.drawString(
  496.                                         this.box.x + this.box.width - 25,
  497.                                         this.box.y + 50,
  498.                                         ">>", STRING::SMALL, STRING::NORMAL, 0);
  499.                                 // } else {
  500.                                 //     canvas.drawString(
  501.                                 //         this.box.x + this.box.width - 25,
  502.                                 //         this.box.y + 50,
  503.                                 //         ">", STRING::SMALL, STRING::NORMAL, 0);
  504.                         }
  505.  
  506.                         if (this.characterLoaded)
  507.                         {
  508.                                 canvas.drawResizedSprite(
  509.                                         this.characterBox.x, this.characterBox.y,
  510.                                         ANIM::CUSTOM[this.characterCID], 0, 0,
  511.                                         this.characterScaleX, this.characterScaleY);
  512.                         }
  513.                 }
  514.         }
  515.  
  516.         void update()
  517.         {
  518.                 if (this.visible && this.lastCharTick + this.speed < jjGameTicks)
  519.                 {
  520.                         if (uint(jjGetStringWidth(this.text, STRING::MEDIUM, normalTextAppearance)) >= this.box.y)
  521.                         {
  522.                                 this.textDisplayed = this.text.substr(0, this.textDisplayed.length() + 1) + "@";
  523.                         }
  524.                         else
  525.                         {
  526.                                 this.textDisplayed = this.text.substr(0, this.textDisplayed.length() + 1);
  527.                         }
  528.  
  529.                         if (getStringLength(this.textDisplayed) >= getStringLength(this.text))
  530.                         {
  531.                                 this.finished = true;
  532.                         }
  533.  
  534.                         lastCharTick = jjGameTicks;
  535.                 }
  536.         }
  537.  
  538.         void input(jjPLAYER @player)
  539.         {
  540.                 if (this.visible)
  541.                 {
  542.                         if (jjKey[KEYS[85].code] && this.keyCooldown == false)
  543.                         {
  544.                                 if (this.finished || this.can_skip)
  545.                                         this.end();
  546.  
  547.                                 if (!this.finished && this.can_skip)
  548.                                         this.skipped = true;
  549.                         }
  550.  
  551.                         if (this.choice < 0)
  552.                                 this.choice = 0;
  553.                         if (this.choice > (this.choices.length - 2))
  554.                                 this.choice = this.choices.length - 1;
  555.  
  556.                         // up
  557.                         if (jjKey[KEYS[30].code])
  558.                         {
  559.                                 // this is because if we get a negative value then the number is over 416k
  560.                                 if (!(this.choice - 1 > this.choices.length + 1))
  561.                                         this.choice -= 1;
  562.                         }
  563.  
  564.                         // down
  565.                         if (jjKey[KEYS[31].code])
  566.                         {
  567.                                 this.choice += 1;
  568.                         }
  569.  
  570.                         this.keyCooldown = true;
  571.  
  572.                         dictionary dict = {{"dialogue", @ this}};
  573.  
  574.                         TimerV(
  575.                                 80, function(this) {
  576.                                         Dialogue @dialog;
  577.                                         this.get("dialogue", @dialog);
  578.  
  579.                                         dialog.keyCooldown = false;
  580.                                 },
  581.                                 dict);
  582.                 }
  583.         }
  584.  
  585.         void end()
  586.         {
  587.                 if (this.choices.length != 0)
  588.                 {
  589.                         if (this.finished)
  590.                         {
  591.                                 if (
  592.                                         (this.choices[this.choice])
  593.                                                 .callback(
  594.                                                         @(this.choices[this.choice]), @ this))
  595.                                 {
  596.                                         this.visible = false;
  597.                                 }
  598.  
  599.                                 return;
  600.                         }
  601.                 }
  602.  
  603.                 this.visible = false;
  604.                 this.finished = true;
  605.         }
  606. }
  607.  
  608. // incomplete
  609. enum RabbitState {
  610.         IDLE,
  611.         WALKING,
  612.         RUNNING,
  613.         JUMPING,
  614.         FALLING,
  615.         DYING,
  616.         DEAD,
  617.         SHOOTING,
  618.         PUSHING,
  619.         HURT
  620. };
  621.  
  622. class RabbitFur {
  623.         // this isn't RGBA but its instead of using "abcd"
  624.         int r, g, b, a;
  625.  
  626.         RabbitFur(int r, int g, int b, int a) {
  627.                 this.r = r;
  628.                 this.g = g;
  629.                 this.b = b;
  630.                 this.a = a;
  631.         }
  632.  
  633.         // use SPRITE::PLAYER and spriteParam as the result
  634.         int emulateFur() {
  635.                 getFreePlayer().furSet(this.r, this.g, this.b, this.a);
  636.  
  637.                 return getFreePlayer().clientID;
  638.         }
  639. }
  640.  
  641. class RabbitNPC {
  642.         RabbitState state;
  643.         string name;
  644.         RabbitFur@ fur;
  645.  
  646.         RabbitNPC(string name, RabbitFur fur) {
  647.                 this.name = name;
  648.                 @this.fur  = fur;
  649.                 this.state = RabbitState::IDLE;
  650.         }
  651. }
  652.  
  653. jjPLAYER@ getFreePlayer() {
  654.         for (int i = 0; i < 32; i++)
  655.         {
  656.                 if (!jjPlayers[i].isActive)
  657.                         return jjPlayers[i];
  658.         }
  659.  
  660.         return jjPlayers[1];
  661. }
  662.  
  663. uint getStringLength(string str)
  664. {
  665.         string str2 = str;
  666.         uint i = 0;
  667.  
  668.         while (i < str2.length())
  669.         {
  670.                 if (str2[i] == "|"[0])
  671.                 {
  672.                         str2 = str2.substr(0, i) + str2.substr(i + 1);
  673.                 }
  674.  
  675.                 i++;
  676.         }
  677.  
  678.         return str2.length();
  679. }
  680.  
  681. uint getStringHeight(string str)
  682. {
  683.         uint height = 0;
  684.  
  685.         for (uint i = 0; i < str.length(); i++)
  686.         {
  687.                 if (str[i] == "@"[0])
  688.                 {
  689.                         height += 1;
  690.                 }
  691.         }
  692.  
  693.         return height * 20;
  694. }
  695.  
  696. bool parseBool(string str)
  697. {
  698.         if (str == "true" || str == "1" || str == "yes")
  699.                 return true;
  700.         return false;
  701. }
  702.  
  703. string formatBool(bool b)
  704. {
  705.         if (b)
  706.                 return "1";
  707.         return "0";
  708. }
  709.  
  710. string formatSize(STRING::Size size)
  711. {
  712.         if(size == STRING::SMALL) return "small";
  713.         if(size == STRING::MEDIUM) return "medium";
  714.         return "large";
  715. }
  716.  
  717. STRING::Size parseSize(string size)
  718. {
  719.         if(size == "small") return STRING::SMALL;
  720.         if(size == "medium") return STRING::MEDIUM;
  721.         return STRING::LARGE;
  722. }
  723.  
  724. string formatBoolToStringInteger(bool b)
  725. {
  726.         if (b)
  727.                 return "1";
  728.         return "0";
  729. }
  730.  
  731. CHAR::Char parseCharacter(string str)
  732. {
  733.         if (str == "SPAZ")
  734.                 return CHAR::SPAZ;
  735.         if (str == "LORI")
  736.                 return CHAR::LORI;
  737.         if (str == "BIRD")
  738.                 return CHAR::BIRD;
  739.         if (str == "FROG")
  740.                 return CHAR::FROG;
  741.         if (str == "BIRD2")
  742.                 return CHAR::BIRD2;
  743.  
  744.         return CHAR::JAZZ;
  745. }
  746.  
  747. string formatCharacter(CHAR::Char charc)
  748. {
  749.         if (charc == CHAR::SPAZ)
  750.                 return "SPAZ";
  751.         if (charc == CHAR::LORI)
  752.                 return "LORI";
  753.         if (charc == CHAR::BIRD)
  754.                 return "BIRD";
  755.         if (charc == CHAR::FROG)
  756.                 return "FROG";
  757.         if (charc == CHAR::BIRD2)
  758.                 return "BIRD2";
  759.  
  760.         return "JAZZ";
  761. }
  762.  
  763. GEM::Color parseGem(string str)
  764. {
  765.         if (str == "GREEN")
  766.                 return GEM::GREEN;
  767.         if (str == "BLUE")
  768.                 return GEM::BLUE;
  769.         if (str == "PURPLE")
  770.                 return GEM::PURPLE;
  771.  
  772.         return GEM::RED;
  773. }
  774.  
  775. string formatGem(GEM::Color g)
  776. {
  777.         if (g == GEM::GREEN)
  778.                 return "GREEN";
  779.         if (g == GEM::BLUE)
  780.                 return "BLUE";
  781.         if (g == GEM::PURPLE)
  782.                 return "PURPLE";
  783.  
  784.         return "RED";
  785. }
  786.  
  787. array<string> cloneStringArray(array<string> arr)
  788. {
  789.         array<string> newArray;
  790.  
  791.         for (uint itemIndex = 0; itemIndex < arr.length; itemIndex++)
  792.         {
  793.                 newArray.insertLast(arr[itemIndex]);
  794.         }
  795.  
  796.         return newArray;
  797. }
  798.  
  799. int boolToInt(bool b)
  800. {
  801.         if (b)
  802.                 return 1;
  803.         else
  804.                 return 0;
  805. }
  806.  
  807. string getPipeColor(int pipeCount)
  808. {
  809.         string color = "white";
  810.  
  811.         switch (pipeCount)
  812.         {
  813.         case 1:
  814.                 color = "green";
  815.                 break;
  816.         case 2:
  817.                 color = "red";
  818.                 break;
  819.         case 3:
  820.                 color = "blue";
  821.                 break;
  822.         case 4:
  823.                 color = "yellow";
  824.                 break;
  825.         case 5:
  826.                 color = "pink";
  827.                 break;
  828.         case 6:
  829.                 color = "white";
  830.                 break;
  831.         case 7:
  832.                 color = "green";
  833.                 break;
  834.         case 8:
  835.                 color = "cyan";
  836.                 break;
  837.         }
  838.  
  839.         return color;
  840. }
  841.  
  842. string restartPipePattern(string str)
  843. {
  844.         // fix this
  845.         // w|g|r|b|y|p|w|g|c|(restart from g)
  846.         // white-green-red-blue-yellow-pink-white(ish)-green-cyan(i think)
  847.  
  848.         int pipeCount = 0;
  849.         string color = "white";
  850.  
  851.         for (uint i = 0; i < str.length(); i++)
  852.         {
  853.                 if (str[i] == "|"[0])
  854.                 {
  855.                         pipeCount += 1;
  856.  
  857.                         if (pipeCount > 8)
  858.                         {
  859.                                 pipeCount = 1;
  860.                         }
  861.                 }
  862.         }
  863.  
  864.         color = getPipeColor(pipeCount);
  865.  
  866.         while (color != "white")
  867.         {
  868.                 str = str + "|";
  869.  
  870.                 pipeCount += 1;
  871.  
  872.                 if (pipeCount > 8)
  873.                 {
  874.                         pipeCount = 1;
  875.                 }
  876.         }
  877.  
  878.         return str;
  879. }
  880.  
  881. Key @isAnyKeyDown()
  882. {
  883.         Key @keyThatIsDown;
  884.  
  885.         for (uint i = 0; i < KEYS.length() - 1; i++)
  886.         {
  887.                 Key @key = KEYS[i];
  888.  
  889.                 if (jjKey[key.code])
  890.                 {
  891.                         @keyThatIsDown = key;
  892.                 }
  893.         }
  894.  
  895.         return keyThatIsDown;
  896. }
  897.  
  898. bool isKeyDown(Key @key)
  899. {
  900.         return jjKey[key.code];
  901. }
  902.  
  903. Key @getKeyById(string id)
  904. {
  905.         Key @foundKey;
  906.  
  907.         for (uint i = 0; i < KEYS.length() - 1; i++)
  908.         {
  909.                 Key @key = KEYS[i];
  910.  
  911.                 if (key.id == id)
  912.                 {
  913.                         @foundKey = key;
  914.                         break;
  915.                 }
  916.         }
  917.  
  918.         return foundKey;
  919. }
  920.  
  921. int getRandomNumber(int min, int max)
  922. {
  923.         int num = stvutilRNG();
  924.  
  925.         if (num < 0)
  926.                 num *= -1;
  927.  
  928.         num = (num % (max - min + 1)) + min;
  929.  
  930.         return num;
  931. }
  932.  
  933. int getPlayerCount()
  934. {
  935.         int count = 0;
  936.  
  937.         for (int i = 0; i < 32; i++)
  938.         {
  939.                 if (jjPlayers[i].isActive)
  940.                         count++;
  941.         }
  942.  
  943.         return count;
  944. }
  945.  
  946. jjPLAYER @getRandomPlayer()
  947. {
  948.         jjPLAYER @user = jjPlayers[getRandomNumber(0, getPlayerCount())];
  949.  
  950.         if (user.isActive and !user.isOut)
  951.                 return user;
  952.         else
  953.                 return getRandomPlayer();
  954. }
  955.  
  956. funcdef void KeyPressCallback(uint);
  957.  
  958. array<bool> prevKeys(256, false);
  959. array<KeyPressCallback@> keyPressCallbacks;
  960.  
  961. void updateKeys()
  962. {
  963.     for (uint keyCode = 0; keyCode < 256; keyCode++)
  964.     {
  965.         if (jjKey[keyCode] && !prevKeys[keyCode])
  966.         {
  967.             for (uint i = 0; i < keyPressCallbacks.length; i++)
  968.             {
  969.                 keyPressCallbacks[i](keyCode);
  970.             }
  971.         }
  972.  
  973.         prevKeys[keyCode] = jjKey[keyCode];
  974.     }
  975. }