+
+The candy merchant: snd ( found here )
+The lollipops farm: jgs ( found here )
+Potions: inspired by lbm & ejm97 ( found here )
+Scroll: inspired by hjw ( found here )
+
+
+Hey, you can only eat candies or throw them on the ground, this is stupid!
+
+ Just be patient! ;)
+
+I have my 5 characters name, but I don't know how to load my game!
+
+ When you click the "Save" button, a link appears next to it. You just have to click this link, and you will load your saved game. You can even put the link in your bookmarks, if you want!
+
+ If you didn't keep the link but you have your 5 characters name, then just use the load button.
+
+My lollipop production at the farm is stuck.. it's written I should have x/day or x/hour but I don't get anything..
+
+ Well, you'll get your lollipops, but it's real hours and real days... you should plant more lollipops to reach an x/min production, it will be more efficient!
+
+I can't find the answer to a question of the frog :'(
+
+ You can ask a friend for help! Answers are often simple, but a little bit twisted.
+
+I can go to the forge, but all I see is "There's an anvil here.", when can I do ?
+
+ You don't have the appropriate sword yet.. did you answer all the frog's questions? ;)
+
+I can't buy the 60k spell at the hut!
+
+ The sorceress, since she is a sorceress, can only work on magic swords. This is why you have to enchant your sword before being able to buy this spell!
+
+I can see the cauldron in my inventory, but I can't have access to it?!
+
+ This bug seems to happen on Chromium-based browsers (Chrome, for example), on some computers.
+ Even if you don't see the cauldron tab on top of the page, you should still be able to access it with the 'right' key of your keyboard.
+
+I found a bug!
+
+ Go tell Scrabble in the least annoying way possible and not during instruction time! There may be tickets involved if it's a bug I haven't heard before...
+
+ Real-life bugs are always reported to Cajun, the janitor. Tell him I sent you.
+
+
+ You are inside the developper's computer !
+ This computer is able to affect the game in the strangest ways...
+ But, as usual, it's not free : you need lollipops to fully access the computer and execute bugs.
+ (1 mlp means 1 000 000 lollipops)
+ You currently have mlp.
+
+
+
+
+
+ No level 6 bug, sorry :( (maybe level 7 ?)
+ Crap, no level 7 bug either :s Don't give up !
+
+ (*) : the effect will last until the next loading (hey, it's a bug after all)
+
+ Welcome to the bug factory !
+ You now have access to the entire computer, and you can therefore create your own bugs.
";
+ this.textActions += "";
+ },
+
+ increaseActionTimer : function(){
+ this.setActionTimer(this.actionTimer + 1);
+ },
+
+ setActionTimer : function(value){
+ // We set the value
+ this.actionTimer = value;
+
+ // We change on the page
+ if(this.weAreMixing){
+ if(this.actionTimer < 60){
+ // If we just began mixing or we're mixing something
+ if(this.actionTimer < 5 || (this.candiesInTheCauldron != 0 || this.lollipopsInTheCauldron != 0)){
+ // We show the timer
+ htmlInteraction.setInnerHtml("cauldron_timer", this.actionTimer);
+ }
+ // Else
+ else{
+ // We show a special message
+ htmlInteraction.setInnerHtml("cauldron_timer", this.actionTimer + " ... You do realize that you're not mixing anything, right ?");
+ }
+ }
+ else
+ htmlInteraction.setInnerHtml("cauldron_timer", "too much mixing, your arms are hurting.");
+ }
+ else if(this.weAreBoiling){
+ if(this.actionTimer < 3)
+ htmlInteraction.setInnerHtml("cauldron_timer", "cold.");
+ else if(this.actionTimer < 6)
+ htmlInteraction.setInnerHtml("cauldron_timer", "lukewarm.");
+ else if(this.actionTimer < 9)
+ htmlInteraction.setInnerHtml("cauldron_timer", "hot..");
+ else if(this.actionTimer < 11)
+ htmlInteraction.setInnerHtml("cauldron_timer", "very hot...");
+ else if(this.actionTimer < 13)
+ htmlInteraction.setInnerHtml("cauldron_timer", "very very hot !");
+ else if(this.actionTimer < 14)
+ htmlInteraction.setInnerHtml("cauldron_timer", "bubbles begin to appear...");
+ else if(this.actionTimer < 15)
+ htmlInteraction.setInnerHtml("cauldron_timer", "bubbles begin to appear... and..");
+ else if(this.actionTimer < 32)
+ htmlInteraction.setInnerHtml("cauldron_timer", "BOILING !");
+ else
+ htmlInteraction.setInnerHtml("cauldron_timer", "the water is burnt ! How is that even possible ?");
+ }
+ },
+
+ setWeAreMixing : function(value){
+ // If we want to stop mixing
+ if(value == false && this.weAreMixing == true){
+ // Then we stop
+ this.weAreMixing = false;
+ // We register the mixing
+ this.registerAction("mix", this.candiesWhenWeBeganAction, this.lollipopsWhenWeBeganAction, this.actionTimer);
+ }
+ // Else, if we want to begin mixing
+ else if(value == true && this.weAreMixing == false){
+ // Then we begin
+ this.weAreMixing = true;
+ this.disableActionsButtons();
+ // We set the text
+ htmlInteraction.setInnerHtml("cauldron_action_text", "Mixing...
");
+ // We set the timer
+ this.setActionTimer(0);
+ // We store some info
+ this.candiesWhenWeBeganAction = this.candiesInTheCauldron;
+ this.lollipopsWhenWeBeganAction = this.lollipopsInTheCauldron;
+ }
+ },
+
+ setWeAreBoiling : function(value){
+ // If we want to stop Boiling
+ if(value == false && this.weAreBoiling == true){
+ // Then we stop
+ this.weAreBoiling = false;
+ // We register the Boiling
+ this.registerAction("boil", this.candiesWhenWeBeganAction, this.lollipopsWhenWeBeganAction, this.actionTimer);
+ }
+ // Else, if we want to begin Boiling
+ else if(value == true && this.weAreBoiling == false){
+ // Then we begin
+ this.weAreBoiling = true;
+ this.disableActionsButtons();
+ // We set the text
+ htmlInteraction.setInnerHtml("cauldron_action_text", "Boiling...
");
+ // We set the timer
+ this.setActionTimer(0);
+ // We store some info
+ this.candiesWhenWeBeganAction = this.candiesInTheCauldron;
+ this.lollipopsWhenWeBeganAction = this.lollipopsInTheCauldron;
+ }
+ },
+
+ putIntoBottles : function(){
+ // We create the vars which will store the results for a final drawing on the page
+ var resultsList = [];
+ var resultsText = "";
+
+ // We store actions into vars for easier use
+ var lastAc = this.actionsList[this.actionsList.length - 1];
+ var lastLastAc = this.actionsList[this.actionsList.length - 2];
+ var lastLastLastAc = this.actionsList[this.actionsList.length - 3];
+
+ // Check for minor health potion
+ if(lastAc.type == "mix" // Last action was mixing
+ && lastAc.nbrLollipops == 0 // We mixed no lollipop
+ && lastAc.nbrCandies > 0 // We mixed at least one candy
+ && lastAc.nbrCandies % 100 == 0 // The candies we mixed were a multiple of 100
+ && lastAc.nbrCandies == this.candiesInTheCauldron && lastAc.nbrLollipops == this.lollipopsInTheCauldron // We didn't add anything while mixing
+ && lastAc.timer >= 11 && lastAc.timer <= 19){ // It took between 11 and 19 seconds
+ potions.getPotions(potions.list.health, Math.floor(lastAc.nbrCandies/100)); // We add the potions to our stock
+ resultsList.push({type:"minor health", nbr:Math.floor(lastAc.nbrCandies/100)}); // We add the result to the list
+ }
+
+ // Check for major health potion
+ if(lastAc.type == "mix" // Last action was mixing
+ && lastAc.nbrLollipops > 0 // We mixed at least one lollipop
+ && lastAc.nbrLollipops % 100 == 0 // The lollipops we mixed were a multiple of 100
+ && lastAc.nbrCandies == 0 // We mixed no candy
+ && lastAc.nbrLollipops == this.lollipopsInTheCauldron // We didn't add any lollipop while mixing
+ && this.candiesInTheCauldron == lastAc.nbrLollipops // While mixing, we added as many candies as we had lollipops at the beginning
+ && lastAc.timer >= 16 && lastAc.timer <= 24){ // It took between 16 and 24 seconds
+ potions.getPotions(potions.list.majorHealth, Math.floor(lastAc.nbrLollipops/100)); // We add the potions to our stock
+ resultsList.push({type:"major health", nbr:Math.floor(lastAc.nbrLollipops/100)}); // We add the result to the list
+ }
+
+ // Check for turtle potion
+ if(
+ /* LAST ACTION */
+ lastAc.type == "boil" // Last action was boiling
+ && lastAc.nbrCandies == 0 // We boiled no candy
+ && lastAc.nbrLollipops > 0 // We boiled at least one lollipop
+ && lastAc.nbrLollipops % 20000 == 0 // The lollipops we boiled were a multiple of 20000
+ && lastAc.nbrLollipops == this.lollipopsInTheCauldron // We didn't add any lollipop while boiling
+ && lastAc.nbrCandies == this.candiesInTheCauldron // We didn't add any candy while boiling
+ && lastAc.timer >= 15 && lastAc.timer < 32 // It was boiling when we stopped boiling
+ /* LAST LAST ACTION */
+ && lastLastAc.type == "mix" // Last last action was mixing
+ /* LAST LAST LAST ACTION */
+ && lastLastLastAc.type == "boil" // Last last last action was boiling
+ && lastLastLastAc.nbrCandies == 0 // We boiled no candy
+ && lastLastLastAc.nbrLollipops > 0 // We boiled at least one lollipop
+ && lastLastLastAc.nbrLollipops % 10000 == 0 // The lollipops we boiled were a multiple of 10000
+ && lastLastLastAc.timer >= 15 && lastLastLastAc.timer < 32 // It was boiling when we stopped boiling
+ /* STUFF BETWEEN ACTIONS */
+ && lastAc.nbrLollipops == 2 * lastLastLastAc.nbrLollipops){ // We boiled at the end twice more lollipops than what we boiled at first
+ potions.getPotions(potions.list.turtle, Math.floor(lastAc.nbrLollipops/20000)); // We add the potions to our stock
+ resultsList.push({type:"turtle", nbr:Math.floor(lastAc.nbrLollipops/20000)}); // We add the result to the list
+ }
+
+ // Check for invulnerability potion
+ if(lastAc.type == "mix" // Last action was mixing
+ && lastAc.nbrLollipops == 0 // We mixed no lollipop
+ && lastAc.nbrCandies > 0 // We mixed at least one candy
+ && lastAc.nbrCandies % 2000 == 0 // The candies we mixed were a multiple of 2000
+ && lastAc.nbrCandies == this.candiesInTheCauldron && lastAc.nbrLollipops == this.lollipopsInTheCauldron // We didn't add anything while mixing
+ && lastAc.timer >= 60){ // It took >= 60 seconds
+ potions.getPotions(potions.list.invulnerability, Math.floor(lastAc.nbrCandies/2000)); // We add the potions to our stock
+ resultsList.push({type:"invulnerability", nbr:Math.floor(lastAc.nbrCandies/2000)}); // We add the result to the list
+ }
+
+ // Check for cloning potion
+ if(lastAc.type == "boil" // Last action was boiling
+ && lastAc.nbrLollipops == 0 // We boiled no lollipop
+ && lastAc.nbrCandies == 0 // We boiled no candy
+ && this.lollipopsInTheCauldron == 0 // We didn't add any lollipop while boiling
+ && this.convertCandiesToPotionsForTheCloningPotion(this.candiesInTheCauldron) > 0 // With the candies we added while boiling (or after), we can make at least one potion
+ && lastAc.timer >= 32){ // The water burnt while boiling
+ potions.getPotions(potions.list.cloning, this.convertCandiesToPotionsForTheCloningPotion(this.candiesInTheCauldron)); // We add the potions to our stock
+ resultsList.push({type:"cloning", nbr:this.convertCandiesToPotionsForTheCloningPotion(this.candiesInTheCauldron)}); // We add the result to the list
+ }
+
+ // Check for G.M.O.O.H. potion
+ if(lastAc.type == "mix" // Last action was mixing
+ && lastAc.nbrLollipops > 0 // We mixed at least one lollipop
+ && lastAc.nbrLollipops % 500 == 0 // The lollipops we mixed were a multiple of 500
+ && lastAc.nbrCandies == 10000 // We mixed 10000 candies
+ && this.candiesInTheCauldron == lastAc.nbrCandies // We didn't add any candy while mixing
+ && this.lollipopsInTheCauldron == lastAc.nbrLollipops){ // We didn't add any lollipop while mixing
+ potions.getPotions(potions.list.gmooh, Math.floor(lastAc.nbrLollipops/500)); // We add the potions to our stock
+ resultsList.push({type:"G.M.O.O.H.", nbr:Math.floor(lastAc.nbrLollipops/500)}); // We add the result to the list
+ }
+
+ // Check for superman potion
+ if(lastAc.type == "mix" // Last action was mixing
+ && lastAc.nbrLollipops == 0 // We mixed no lollipop
+ && lastAc.nbrCandies > 0 // We mixed at least one candy
+ && lastAc.nbrCandies % 180 == 0 // The candies we mixed were a multiple of 180
+ && lastAc.nbrCandies == this.candiesInTheCauldron && lastAc.nbrLollipops == this.lollipopsInTheCauldron){ // We didn't add anything while mixing
+ potions.getPotions(potions.list.superman, Math.floor(lastAc.nbrCandies/180)); // We add the potions to our stock
+ resultsList.push({type:"superman", nbr:Math.floor(lastAc.nbrCandies/180)}); // We add the result to the list
+ }
+
+ // Check for seed
+ if(lastAc.type == "boil" // Last action was boiling
+ && lastAc.nbrLollipops == 0 // We boiled no lollipop
+ && lastAc.nbrCandies == 0 // We boiled no candy
+ && this.lollipopsInTheCauldron == 0 // We didn't add any lollipop while boiling
+ && this.candiesInTheCauldron > 0 // We added at least one candy while or after boiling
+ && this.candiesInTheCauldron % 650 == 0){ // The candies we added while or after boiling are a multiple of 650
+ potions.getPotions(potions.list.seed, Math.floor(this.candiesInTheCauldron/650)); // We add the potions to our stock
+ resultsList.push({type:"seed", nbr:Math.floor(this.candiesInTheCauldron/650), special:true, plural:"seeds"}); // We add the result to the list
+ }
+
+ // Check for jelly
+ if(
+ /* ACTIONS TYPES */
+ lastAc.type == "boil" // Last action was boiling
+ && lastLastAc.type == "mix" // Last last action was mixing
+ && lastLastLastAc.type == "boil" // Last last last action was boiling
+ /* LAST LAST LAST ACTION */
+ && lastLastLastAc.nbrLollipops == 0 // No lollipop
+ && lastLastLastAc.nbrCandies > 0 // At least one candy
+ && lastLastLastAc.nbrCandies % 600 == 0 // Candies multiple of 600
+ /* LAST LAST ACTION */
+ && lastLastAc.nbrLollipops > 0 // At least one lollipop
+ && lastLastAc.nbrLollipops % 6000 == 0 // Lollipops mutiple of 6000
+ && lastLastAc.nbrLollipops == 10*lastLastLastAc.nbrCandies // Lollipops = 10*candies of last last last action
+ && lastLastAc.nbrCandies == lastLastLastAc.nbrCandies // As many candies as last last last action
+ /* LAST ACTION */
+ && lastAc.nbrLollipops == lastLastAc.nbrLollipops // As many lollipops as last last action
+ && lastAc.nbrCandies == lastLastLastAc.nbrCandies*2 // Twice more candies than last last last action
+ && lastAc.nbrLollipops == this.lollipopsInTheCauldron // We didn't add any lollipop
+ && lastAc.nbrCandies == this.candiesInTheCauldron){ // We didn't add any candy
+ potions.getPotions(potions.list.jelly, Math.floor(lastAc.nbrCandies/600)); // We add the potions to our stock
+ resultsList.push({type:"jelly", nbr:Math.floor(lastAc.nbrCandies/600), special:true, plural:"jellies"}); // We add the result to the list
+ }
+
+ // We show the result on the page if there's any result
+ if(resultsList.length > 0){
+ for(var i = 0; i < resultsList.length; i++){
+ if(resultsList[i].special != true){
+ if(resultsList[i].nbr > 1){
+ resultsText += "You made " + resultsList[i].nbr + " " + resultsList[i].type + " potions ! ";
+ }
+ else{
+ resultsText += "You made a " + resultsList[i].type + " potion. ";
+ }
+ }
+ else{
+ if(resultsList[i].nbr > 1){
+ resultsText += "You made " + resultsList[i].nbr + " " + resultsList[i].plural + " ! ";
+ }
+ else{
+ resultsText += "You made a " + resultsList[i].type + ". ";
+ }
+ }
+ }
+ htmlInteraction.setInnerHtml("cauldron_results_text", resultsText);
+ }
+ else{
+ htmlInteraction.setInnerHtml("cauldron_results_text", "You don't manage to get anything interesting with that preparation. Did you follow the manual's instructions ?");
+ }
+
+ // We empty the cauldron
+ this.setCandiesInTheCauldron(0);
+ this.setLollipopsInTheCauldron(0);
+
+ // We reset the actions list
+ this.actionsList = [{type:"none"}, {type:"none"}, {type:"none"}];
+ },
+
+ convertCandiesToPotionsForTheCloningPotion : function(howMuch){
+ return Math.floor(howMuch / 1337);
+ },
+
+ disableActionsButtons : function(){
+ // We disable the mixing button
+ htmlInteraction.disableButton("cauldron_mix");
+ // We disable the put into bottles button
+ htmlInteraction.disableButton("cauldron_put_into_bottles");
+ // We disable the boiling button
+ htmlInteraction.disableButton("cauldron_boil");
+ // We enable the stopping button
+ htmlInteraction.enableButton("cauldron_stop");
+ },
+
+ enableActionsButtons : function(){
+ // We re enable the mixing button
+ htmlInteraction.enableButton("cauldron_mix");
+ // We re enable the put into bottles button
+ htmlInteraction.enableButton("cauldron_put_into_bottles");
+ // We re enable the boiling button
+ htmlInteraction.enableButton("cauldron_boil");
+ // We disable the button
+ htmlInteraction.disableButton("cauldron_stop");
+ },
+
+ stopActions : function(){
+ // Stop all actions
+ this.setWeAreMixing(false);
+ this.setWeAreBoiling(false);
+
+ // Re enable buttons
+ this.enableActionsButtons();
+
+ // Empty the action text
+ htmlInteraction.setInnerHtml("cauldron_action_text", "");
+ },
+
+ putInTheCauldron : function(){
+ // We get the values of the text inputs
+ var candiesInput = htmlInteraction.getElement("cauldron_candies_quantity").value;
+ var lollipopsInput = htmlInteraction.getElement("cauldron_lollipops_quantity").value;
+
+ // We get the quantities
+ if(candiesInput != ""){
+ var candiesQuantity = parseInt(candiesInput);
+ }
+ else candiesQuantity = 0;
+
+ if(lollipopsInput != ""){
+ var lollipopsQuantity = parseInt(lollipopsInput);
+ }
+ else lollipopsQuantity = 0;
+
+ // If the quantities are incorrect
+ if(isNaN(candiesQuantity) || isNaN(lollipopsQuantity)){
+ // If both values are incorrect
+ if(isNaN(candiesQuantity) && isNaN(lollipopsQuantity)){
+ htmlInteraction.setInnerHtml("cauldron_comment", "The values you entered are not numbers.");
+ }
+ // If only the candies value is incorrect
+ else if(isNaN(candiesQuantity)){
+ htmlInteraction.setInnerHtml("cauldron_comment", "The value you entered for candies is not a number.");
+ }
+ // Else, only the lollipops value is incorrect
+ else{
+ htmlInteraction.setInnerHtml("cauldron_comment", "The value you entered for lollipops is not a number.");
+ }
+ }
+ // Else, if we don't have enough candies or lollipops to put all that in the cauldron
+ else if(candiesQuantity > candies.nbrOwned || lollipopsQuantity > lollipops.nbrOwned){
+ htmlInteraction.setInnerHtml("cauldron_comment", "You don't have enough to put all that in the cauldron !");
+ }
+ // Else, if one if the value is negative
+ else if(candiesQuantity < 0 || lollipopsQuantity < 0){
+ htmlInteraction.setInnerHtml("cauldron_comment", "Don't put negative values !");
+ }
+ // Else, we put all that in the cauldron !
+ else{
+ htmlInteraction.setInnerHtml("cauldron_comment", ""); // We empty the comment
+ // We clear the text inputs
+ htmlInteraction.getElement("cauldron_candies_quantity").value = "";
+ htmlInteraction.getElement("cauldron_lollipops_quantity").value = "";
+ // We substract candies from our stock
+ candies.setNbrOwned(candies.nbrOwned - candiesQuantity);
+ lollipops.setNbrOwned(lollipops.nbrOwned - lollipopsQuantity);
+ // And we add them in the cauldron
+ this.setCandiesInTheCauldron(this.candiesInTheCauldron + candiesQuantity);
+ this.setLollipopsInTheCauldron(this.lollipopsInTheCauldron + lollipopsQuantity);
+ }
+ },
+
+ setCandiesInTheCauldron : function(value){
+ this.candiesInTheCauldron = value;
+ this.updateActionsInCauldronOnPage();
+ },
+
+ setLollipopsInTheCauldron : function(value){
+ this.lollipopsInTheCauldron = value;
+ this.updateActionsInCauldronOnPage();
+ },
+
+ updateCauldronOnPage : function(){
+ this.resetCauldronText();
+ this.drawCauldron();
+ htmlInteraction.setInnerHtml("cauldron_cauldron", this.textCauldron.join(""));
+ },
+
+ updateBookOnPage : function(){
+ this.resetBookText();
+ this.drawBook();
+ htmlInteraction.setInnerHtml("cauldron_book", this.textBook.join(""));
+ },
+
+ updateActionsInfoOnPage : function(){
+ this.textActionsInfo = "";
+ this.drawActionsInfo();
+ htmlInteraction.setInnerHtml("cauldron_actions_info", this.textActionsInfo);
+ },
+
+ updateActionsPutOnPage : function(){
+ this.textActionsPut = "";
+ this.drawActionsPut();
+ htmlInteraction.setInnerHtml("cauldron_actions_put", this.textActionsPut);
+ },
+
+ updateActionsInCauldronOnPage : function(){
+ this.textActionsInCauldron = "";
+ this.drawActionsInCauldron();
+ htmlInteraction.setInnerHtml("cauldron_actions_in_cauldron", this.textActionsInCauldron);
+ },
+
+ updateActionsOnPage : function(){
+ this.textActions = "";
+ this.drawActions();
+ htmlInteraction.setInnerHtml("cauldron_actions", this.textActions);
+ },
+
+ // Ascii
+ asciiCauldron :
+[
+" ___________",
+" (___________)",
+" / \\",
+" / \\",
+" | |",
+" ____\\ /____",
+"()____\'.__ __.\'____()",
+" .\'` .\'```\'. `-.",
+" ().\'` `\'.()"
+],
+
+ asciiBook :
+[
+" ___________________ ___________________",
+" .-/| ~~**~~ \\ / ~~**~~ |\\-.",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" |||| : ||||",
+" ||||___________________ : ___________________||||",
+" ||/====================\\:/====================\\||",
+" `---------------------~___~--------------------\'\'"
+],
+
+ asciiFirstPage :
+[
+"Welcome to the",
+"potions brewing",
+"manual for",
+"beginners !",
+"",
+" (second edition)",
+"",
+" __ __ __ __ ",
+" )( )( )( )( ",
+"(__)(__)(__)(__)"
+],
+
+ asciiSecondPage :
+[
+"",
+"The present",
+"manual will focus",
+"on potions that",
+"require materials",
+"such as : ",
+" - candies",
+" - lollipops",
+],
+
+ asciiThirdPage :
+[
+" The three rules",
+"of potion brewing",
+"-----------------",
+"",
+"1. The effect of",
+"a potion depends",
+"on its content as",
+"well as on the",
+"steps followed to",
+"prepare it."
+],
+
+ asciiFourthPage :
+[
+"2. You can do",
+"several potions",
+"in one go.",
+"",
+"3. It's possible",
+"to mix",
+"instructions to",
+"brew potions of",
+"different types",
+"in one go."
+],
+
+ asciiFifthPage :
+[
+"Table of contents",
+"-----------------",
+" Pages 10 to 20",
+" (Good potions)",
+"-----------------",
+"",
+" 10-13",
+"Minor health",
+"potion"
+],
+
+ asciiSixthPage :
+[
+"",
+" 14-17",
+"Major health",
+"potion",
+"",
+" 18-20",
+"Invulnerability",
+"potion"
+],
+
+ asciiSeventhPage :
+[
+"Table of contents",
+"-----------------",
+" Pages 22 to 41",
+"(Strange potions)",
+"-----------------",
+"",
+" 22-27",
+"Turtle potion"
+],
+
+ asciiEighthPage :
+[
+" 28-33",
+"Cloning potion",
+"",
+" 34-37",
+"G.M.O.O.H.",
+"potion",
+"",
+" 38-41",
+"Superman potion",
+],
+
+ asciiNinthPage :
+[
+"Table of contents",
+"-----------------",
+" Pages 42 to 50",
+"(Various magical",
+"objects you can",
+" brew in your",
+" cauldron)",
+"-----------------"
+],
+
+ asciiTenthPage :
+[
+"",
+"",
+" 42-45",
+"Magical seed",
+"",
+"",
+" 46-50",
+"Magical jelly",
+],
+
+ asciiMinorHealthPotionP1 :
+[
+"Minor health pot.",
+"-----------------",
+"The minor health",
+"potion is the",
+"easiest to brew",
+"for beginners.",
+"",
+"Used during a",
+"quest, it will",
+"make you recover"
+],
+
+ asciiMinorHealthPotionP2 :
+[
+"50 health points.",
+"",
+"For one potion,",
+"you will need 100",
+"candies.",
+"",
+"Put them in the",
+"cauldron and mix",
+"during about 15",
+"seconds."
+],
+
+ asciiMinorHealthPotionP3 :
+[
+"You can mix a",
+"little more or",
+"less longer, it",
+"doesn't matter so",
+"much.",
+"",
+"When you're done,",
+"put the resulting",
+"mixture into",
+"bottles."
+],
+
+ asciiMinorHealthPotionP4 :
+[
+"Congratulations !",
+"You just made",
+"your first minor",
+"health potion !",
+"",
+"",
+"N.B. : use 200",
+"candies for 2",
+"potions, 300 for",
+"3, etc."
+],
+
+ asciiMajorHealthPotionP1 :
+[
+"Major health pot.",
+"-----------------",
+"The major health",
+"potion is a bit",
+"harder to make",
+"than the previous",
+"one.",
+"",
+"But it's also",
+"a lot more",
+],
+
+ asciiMajorHealthPotionP2 :
+[
+"efficient : by",
+"drinking it",
+"during a quest,",
+"you will gain",
+"100 health points",
+"instead of 50.",
+"",
+"How to make a",
+"major health",
+"potion :"
+],
+
+ asciiMajorHealthPotionP3 :
+[
+"1. Put 100",
+"lollipops into",
+"your cauldron.",
+"",
+"2. Begin mixing",
+"forcefully.",
+"",
+"3. While you're",
+"mixing, add 100",
+"candies into the",
+],
+
+ asciiMajorHealthPotionP4 :
+[
+"cauldron.",
+"",
+"4. Stop mixing",
+"after 20 seconds.",
+"",
+"5. Put the result",
+"into bottles.",
+"",
+"6. You're done !"
+],
+
+ asciiInvulnerabilityPotionP1 :
+[
+" Invulnerability",
+" potion",
+"-----------------",
+"",
+"This potion,",
+"although being",
+"quite easy to",
+"brew, require a",
+"lot of candies."
+],
+
+ asciiInvulnerabilityPotionP2 :
+[
+"The recipe is",
+"simple : just",
+"put 2000 candies",
+"inside your",
+"cauldron and mix",
+"them until your",
+"arms hurt.",
+"",
+"This potion will",
+"make you"
+],
+
+ asciiInvulnerabilityPotionP3 :
+[
+"invincible for",
+"some time,",
+"during which you",
+"won't feel any",
+"pain or physical",
+"damage."
+],
+
+ asciiTurtlePotionP1 :
+[
+" Turtle potion",
+"-----------------",
+"A turtle !",
+"A turtle !",
+"Do you want to",
+"become a turtle ?",
+"",
+"You'll be able to",
+"become one with",
+"this fantastic"
+],
+
+ asciiTurtlePotionP2 :
+[
+"potion !",
+"",
+"When you will be",
+"a turtle, you",
+"will resist a lot",
+"more to physical",
+"damage. But you",
+"will be slower,",
+"too."
+],
+
+ asciiTurtlePotionP3 :
+[
+"Now, let's get",
+"down to business.",
+"",
+"Put 10000",
+"lollipops in your",
+"cauldron. Do not",
+"add any candy, or",
+"your potion will",
+"be a failure."
+],
+
+ asciiTurtlePotionP4 :
+[
+"Now, heat up the",
+"cauldron until",
+"your preparation",
+"is boiling.",
+"",
+"When it's boiling,",
+"stop heating it",
+"up and mix a",
+"little bit."
+],
+
+ asciiTurtlePotionP5 :
+[
+"Add the same",
+"quantity of",
+"lollipops as you",
+"put at the",
+"beginning, and,",
+"one more time,",
+"heat up",
+"everything until",
+"it's boiling."
+],
+
+ asciiTurtlePotionP6 :
+[
+"Stop boiling,",
+"put into a bottle,",
+"begin a quest,",
+"drink the potion,",
+"you're a turtle !!",
+"",
+" _ .----.",
+" (_\\/ \\_,",
+" \'uu----uu~\'"
+],
+
+ asciiCloningPotionP1 :
+[
+" Cloning potion",
+"-----------------",
+"There's a little",
+"bit of candies in",
+"everyone of us.",
+"",
+"This is actually",
+"a physical law of",
+"our universe."
+],
+
+ asciiCloningPotionP2 :
+[
+"Now, candies are",
+"a very malleable",
+"material.",
+"",
+"These two facts",
+"led us to the",
+"realisation of",
+"this cloning",
+"potion."
+],
+
+ asciiCloningPotionP3 :
+[
+"The potion will",
+"copy your inner",
+"structure and",
+"make a clone of",
+"you almost",
+"entirely made",
+"of candies",
+"(there's a bit of",
+"water, too)."
+],
+
+ asciiCloningPotionP4 :
+[
+"Steps :",
+"",
+"Burn the water in",
+"your cauldron.",
+"",
+"Then, while it's",
+"still burning,",
+"add as many",
+"candies as you",
+"can."
+],
+
+ asciiCloningPotionP5 :
+[
+"It's simple : the",
+"more candies you",
+"put, the more",
+"potions you'll",
+"get !",
+"",
+"(be sure to put",
+" a minimum",
+"quantity, though)"
+],
+
+ asciiCloningPotionP6 :
+[
+" \\o/ -> \\o/",
+"",
+" ^ |",
+" | V",
+"",
+" \\o/ <- \\o/",
+"",
+" \"The circle",
+" of life\""
+],
+
+ asciiGMOOHPotionP1 :
+[
+"G.M.O.O.H. potion",
+"-----------------",
+"G.M.O.O.H. means",
+"\"Get Me Out Of",
+"Here\".",
+"",
+"This potion is to",
+"be used in",
+"critical",
+"situations."
+],
+
+ asciiGMOOHPotionP2 :
+[
+"It will teleport",
+"you to another",
+"location.",
+"",
+"Maybe it will",
+"be safer, maybe",
+"it won't. Who",
+"knows ?",
+"Quite exciting",
+"isn't it ?"
+],
+
+ asciiGMOOHPotionP3 :
+[
+"First, put in",
+"your cauldron a",
+"base quantity of",
+"10 000 candies.",
+"",
+"Then, add 500",
+"lollipops for",
+"each potion you",
+"want to brew."
+],
+
+ asciiGMOOHPotionP4 :
+[
+"Never change the",
+"base quantity of",
+"10 000 candies.",
+"",
+"Then, mix a little",
+"bit and put into",
+"bottles.",
+"",
+"Enjoy your random",
+"potions !"
+],
+
+ asciiSupermanPotionP1 :
+[
+" Superman potion",
+"-----------------",
+"This potion will",
+"transform you",
+"into Superman,",
+"providing you",
+"a fantastic cape.",
+"",
+"Some people say",
+"that this isn't"
+],
+
+ asciiSupermanPotionP2 :
+[
+"useful.",
+"",
+"We respond them",
+"that it is just",
+"so cooooool !",
+"",
+"Anyway, to make",
+"one :",
+"",
+"Put 180 candies"
+],
+
+ asciiSupermanPotionP3 :
+[
+"in your cauldron.",
+"",
+"Mix them.",
+"",
+"Think about",
+"Superman.",
+"",
+"Think once again.",
+"",
+"Put into bottle."
+],
+
+ asciiSupermanPotionP4 :
+[
+"You're done !",
+"",
+" ___________",
+" /.\'_______` \\",
+" /( <_______`-\'\\",
+" `.`.______ \\.\'",
+" `..-.___>.\'",
+" `.__ .\'",
+" `.\'"
+],
+
+ asciiSeedP1 :
+[
+" Seed",
+"-----------------",
+"According to an",
+"ancient legend,",
+"trees would be",
+"the source of all",
+"candies in the",
+"whole world.",
+"",
+"There would exist"
+],
+
+ asciiSeedP2 :
+[
+"somewhere in the",
+"universe a giant",
+"tree, which",
+"remains unnamed.",
+"",
+"This tree would",
+"provide its",
+"discoverer an",
+"infinite flow of",
+"candies."
+],
+
+ asciiSeedP3 :
+[
+"Anyway, we didn't",
+"find it yet, but",
+"we found that it",
+"was possible to",
+"craft a magical",
+"seed so that it",
+"grows a resistant",
+"tree. And this",
+"can be useful",
+"during a quest."
+],
+
+ asciiSeedP4 :
+[
+"Heat up the water",
+"in your cauldron.",
+"",
+"Add 650 candies,",
+"stop boiling and",
+"put the seed into",
+"a bottle.",
+"",
+"Now, plant some",
+"trees !"
+],
+
+ asciiJellyP1 :
+[
+" Jelly",
+"-----------------",
+"Did you ever",
+"thought about",
+"some kind of bomb",
+"that you could",
+"use during a",
+"quest ? If so,",
+"then this magical",
+"jelly should"
+],
+
+ asciiJellyP2 :
+[
+"please you !",
+"",
+"It is a bit hard",
+"to prepare, but",
+"it's quite",
+"powerful.",
+"",
+"This jelly",
+"explodes on",
+"contact and deals"
+],
+
+ asciiJellyP3 :
+[
+"high damage.",
+"",
+"There are three",
+"peparation steps",
+"which correspond",
+"to the three",
+"layers of the",
+"jelly.",
+"",
+"First step :"
+],
+
+ asciiJellyP4 :
+[
+"Put 600 candies,",
+"boil the water,",
+"stop boiling.",
+"",
+"Second step :",
+"",
+"Add 6 000",
+"lollipops,",
+"mix,",
+"stop mixing."
+],
+
+ asciiJellyP5 :
+[
+"Third step :",
+"",
+"Repeat first step.",
+"",
+"Note that you can",
+"only place the",
+"jelly behind you.",
+"",
+"Good luck for",
+"your quests !"
+],
+
+ asciiEndP1 :
+[
+" ~ The end ~",
+"-----------------",
+"",
+" Thanks for",
+" reading !",
+"",
+"We hope this book",
+"helped you. Feel",
+" free to",
+"redistribute it !",
+],
+
+ asciiEndP2 :
+[
+"Co-authors :",
+"",
+"- the sorceress",
+"- the necromancer",
+"- a shoemaker",
+"- a mathematician",
+"- ???",
+"",
+" Happy brewing ~"
+]
+
+};
diff --git a/static/candies/scripts/chocolateBars.js b/static/candies/scripts/chocolateBars.js
new file mode 100755
index 00000000..0e93fb4b
--- /dev/null
+++ b/static/candies/scripts/chocolateBars.js
@@ -0,0 +1,16 @@
+var chocolateBars = {
+
+ // Variables
+ nbrOwned : 0,
+
+ setNbrOwned : function(value){
+ this.nbrOwned = value;
+
+ if(this.nbrOwned == 0) htmlInteraction.setInnerHtml("chocolate_bars", "You have 0 chocolate bars :(");
+ else if(this.nbrOwned != 1) htmlInteraction.setInnerHtml("chocolate_bars", "You have " + this.nbrOwned + " chocolate bars \\o/ (a bug? Oo)");
+ else htmlInteraction.setInnerHtml("chocolate_bars", "You have 1 chocolate bar! \\o/");
+ htmlInteraction.setElementVisibility("chocolate_bars", true);
+ buttons.checkChocolateBars();
+ }
+
+};
diff --git a/static/candies/scripts/chuckNorris.js b/static/candies/scripts/chuckNorris.js
new file mode 100755
index 00000000..c6378835
--- /dev/null
+++ b/static/candies/scripts/chuckNorris.js
@@ -0,0 +1,134 @@
+var chuckNorris = {
+
+ // Variables
+ size : 35,
+ currentFact : "",
+ factStep : 0,
+ firstContact : false,
+ timeSpent : 0,
+ nextPunch : 0,
+
+ // Functions
+ onload : function(){
+ land.addLand("Chuck Norris", this.size, 8, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ setNextPunch : function(){
+ this.nextPunch = 3 + random.getRandomIntUpTo(7);
+ },
+
+ move : function(){
+ // Get indexes
+ var index = quest.getCharacterIndex();
+ var norrisIndex = this.getChuckNorrisIndex();
+
+ // Increase the fact step
+ if(this.factStep > 15){
+ this.setCurrentFact();
+ }
+ else this.factStep += 1;
+
+ // Possibly make some special action
+ if(norrisIndex != -1){
+ if(this.firstContact == false && index >= 20){
+ if(quest.things[norrisIndex - 1].type == "none"){
+ quest.things[norrisIndex - 1] = quest.things[norrisIndex];
+ quest.things[norrisIndex] = quest.makeNoneThing();
+ }
+ else this.firstContact = true;
+ }
+ else if(this.firstContact == true){
+ // Punch
+ if(index > 0 && this.timeSpent % this.nextPunch == 0 && index == norrisIndex - 1 && quest.things[index - 1].type == "none"){
+ quest.things[index - 1] = quest.things[index];
+ quest.things[index] = quest.things[norrisIndex];
+ quest.things[norrisIndex] = quest.makeNoneThing();
+ this.setNextPunch();
+ }
+ }
+ }
+
+ // Increase the time spent
+ this.timeSpent += 1;
+ },
+
+ getChuckNorrisIndex : function(){
+ for(i = 0; i < quest.things.length; i++){
+ if(quest.things[i].text == "CHN") return i;
+ }
+ return -1;
+ },
+
+ setCurrentFact : function(){
+ this.currentFact = random.pickRandomly(this.facts);
+ this.factStep = 0;
+ },
+
+ load : function(){
+ this.setCurrentFact();
+ this.setNextPunch();
+ quest.things[30] = this.makeChuckNorris();
+ this.firstContact = false;
+ this.timeSpent = 0;
+ },
+
+ makeChuckNorris : function(){
+ return land.createMob("CHN", 1000, 1000, "Chuck Norris", "Chuck Norris. You just can't beat him.", []);
+ },
+
+ getText : function(){
+ // Create the text
+ var text = "";
+
+ text += this.getCurrentFactText();
+ text += "\n\n\n\n";
+
+ for(var i = 0; i < this.size; i++){
+ text += quest.things[i].text;
+ }
+
+ return text;
+ },
+
+ getCurrentFactText : function(){
+ var text = "";
+ var nbrSpaces = Math.floor((this.size*3 - this.currentFact.length)/2);
+
+ for(var i = 0; i < nbrSpaces; i++){
+ text += " ";
+ }
+
+ text += "\"" + this.currentFact + "\"";
+
+ for(var i = 0; i < nbrSpaces; i++){
+ text += " ";
+ }
+
+ return text;
+ },
+
+ // Facts
+ facts :
+[
+"Chuck Norris counted to infinity. Twice.",
+"Chuck Norris' tears cure cancer. Too bad he has never cried.",
+"Chuck Norris does not sleep. He waits.",
+"Chuck Norris can squeeze orange juice out of a lemon.",
+"Superman owns a pair of Chuck Norris pajamas.",
+"Chuck Norris can kill two stones with one bird.",
+"Chuck Norris doesn't read books. He stares them down until he gets the information he wants.",
+"Chuck Norris doesn't have hair on his testicles, because hair does not grow on steel.",
+"Chuck Norris can build a snowman out of rain.",
+"Chuck Norris once punched a man in the soul.",
+"Chuck Norris can drown a fish.",
+"Leaving a criminal in the same room as Chuck Norris is cruel and unusual punishment.",
+"Chuck Norris can pick oranges from an apple tree and make the best lemonade youve ever tasted.",
+"Once a cobra bit Chuck Norris' leg. After five days of excruciating pain, the cobra died.",
+"Chuck Norris doesn't play \"hide-and-seek.\" He plays \"hide-and-pray-I-don't-find-you.\"",
+"Chuck Norris beat the sun in a staring contest.",
+"Chuck Norris makes onions cry.",
+"Chuck Norris can divide by zero.",
+"Chuck Norris hears every tree that falls in the woods."
+]
+
+};
diff --git a/static/candies/scripts/commas.js b/static/candies/scripts/commas.js
new file mode 100755
index 00000000..44c9d4ea
--- /dev/null
+++ b/static/candies/scripts/commas.js
@@ -0,0 +1,3 @@
+function numberWithCommas(x) {
+ return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+}
\ No newline at end of file
diff --git a/static/candies/scripts/computer.js b/static/candies/scripts/computer.js
new file mode 100755
index 00000000..39eea6b4
--- /dev/null
+++ b/static/candies/scripts/computer.js
@@ -0,0 +1,234 @@
+var computer = {
+
+ background : function(){
+ window.setTimeout(this.background.bind(this), 1000 + random.getRandomIntUpTo(4000)); // 5000 milliseconds delay
+
+ var index = Math.round(Math.random() * 9);
+
+ var ColorValue = "FFFFFF"; // default color - white (index = 0)
+
+ if(index == 1)
+ ColorValue = "FFCCCC"; //peach
+ if(index == 2)
+ ColorValue = "CCAFFF"; //violet
+ if(index == 3)
+ ColorValue = "A6BEFF"; //lt blue
+ if(index == 4)
+ ColorValue = "99FFFF"; //cyan
+ if(index == 5)
+ ColorValue = "D5CCBB"; //tan
+ if(index == 6)
+ ColorValue = "99FF99"; //lt green
+ if(index == 7)
+ ColorValue = "FFFF99"; //lt yellow
+ if(index == 8)
+ ColorValue = "FFCC99"; //lt orange
+ if(index == 9)
+ ColorValue = "CCCCCC"; //lt grey
+
+ document.getElementsByTagName("body")[0].style.backgroundColor = "#" + ColorValue;
+ },
+
+ size : function(){
+ window.setTimeout(this.size.bind(this), 1000 + random.getRandomIntUpTo(4000));
+ document.getElementsByTagName("body")[0].style.fontSize = "" + random.getRandomIntUpTo(72) + "px";
+ },
+
+ random : function(){
+ window.setTimeout(this.random.bind(this), 1000 + random.getRandomIntUpTo(4000));
+ candies.setNbrOwned(random.pure2());
+ candies.setNbrThrown(random.pure2());
+ candies.setNbrEaten(random.pure2());
+ candies.setCandiesPerSecond(random.pure2());
+ lollipops.setNbrOwned(random.pure2());
+ farm.setLollipopsPlanted(random.pure2());
+ chocolateBars.setNbrOwned(random.pure2());
+ potions.setPotionNbrOwned(potions.list.impInvocationScroll, random.pure2()); potions.setPotionNbrOwned(potions.list.earthquakeScroll, random.pure2()); potions.setPotionNbrOwned(potions.list.teleportScroll, random.pure2()); potions.setPotionNbrOwned(potions.list.fireScroll, random.pure2()); potions.setPotionNbrOwned(potions.list.acidRainScroll, random.pure2()); potions.updateOnPage();
+ potions.setPotionNbrOwned(potions.list.gmooh, random.pure2()); potions.setPotionNbrOwned(potions.list.superman, random.pure2()); potions.setPotionNbrOwned(potions.list.cloning, random.pure2()); potions.setPotionNbrOwned(potions.list.seed, random.pure2()); potions.setPotionNbrOwned(potions.list.jelly, random.pure2()); potions.setPotionNbrOwned(potions.list.turtle, random.pure2()); potions.setPotionNbrOwned(potions.list.invulnerability, random.pure2()); potions.setPotionNbrOwned(potions.list.majorHealth, random.pure2()); potions.setPotionNbrOwned(potions.list.berserk, random.pure2()); potions.setPotionNbrOwned(potions.list.escape, random.pure2()); potions.setPotionNbrOwned(potions.list.health, random.pure2()); potions.updateOnPage();
+ sword.setName(random.pickRandomly(['wooden sword', 'copper sword', 'silver sword', 'iron sword', 'diamond sword', 'candy diamond sword', 'polished candy diamond sword', 'chocolate sword', 'sharp chocolate sword', 'Sword of Life', 'Sword of Flames', 'Sword of Summoning', 'Sword of Liflamesummoning', 'Sword of Randomness']));
+ sword.setSpecialPower(random.pure2());
+
+ objects.setHaveObject("key", random.flipACoin());
+ objects.setHaveObject("boots", random.flipACoin());
+ objects.setHaveObject("swampMap", random.flipACoin());
+ objects.setHaveObject("hutMap", random.flipACoin());
+ objects.setHaveObject("wellMap", random.flipACoin());
+ objects.setHaveObject("magicianHat", random.flipACoin());
+ objects.setHaveObject("pinkRing", random.flipACoin());
+ objects.setHaveObject("forgeMap", random.flipACoin());
+ objects.setHaveObject("candiesConverter", random.flipACoin());
+ objects.setHaveObject("plateArmour", random.flipACoin());
+ objects.setHaveObject("cauldron", random.flipACoin());
+ objects.setHaveObject("magicalHorn", random.flipACoin());
+ objects.setHaveObject("hornOfPlenty", random.flipACoin());
+ objects.setHaveObject("oldAmulet", random.flipACoin());
+
+ developperComputer.setWon(random.flipACoin());
+
+ candiesConverter.setActivated(random.flipACoin());
+
+ cauldron.setBookPage(random.getRandomIntUpTo(26));
+ cauldron.setCandiesInTheCauldron(random.pure2());
+ cauldron.setLollipopsInTheCauldron(random.pure2());
+
+ switch(random.getRandomIntUpTo(4)){
+ case 0: cauldron.putInTheCauldron(); break;
+ case 1: cauldron.setWeAreMixing(true); break;
+ case 2: cauldron.setWeAreBoiling(true); break;
+ case 3: cauldron.stopActions(); break;
+ case 4: cauldron.putIntoBottles(); break;
+ }
+
+ shop.setClickingOnLollipopStep(random.getRandomIntUpTo(15));
+
+ if(random.flipACoin())
+ quest.setTiredTime(random.pure2());
+ else
+ quest.setTiredTime(0);
+
+ inventory.updateOnPage();
+ },
+
+ textColor : function(){
+ window.setTimeout(this.textColor.bind(this), 1000 + random.getRandomIntUpTo(4000));
+ document.getElementsByTagName("body")[0].style.color = this.randomColor();
+ },
+
+ randomColor : function(){
+ return '#' + ('00000' + (Math.random() * 16777216 << 0).toString(16)).substr(-6);
+ },
+
+ addTab : function(){
+ var text = "
";
+
+ if(random.flipACoin())
+ htmlInteraction.getElement("tabs").innerHTML += text;
+ else
+ htmlInteraction.getElement("tabs").innerHTML = text + htmlInteraction.getElement("tabs").innerHTML;
+ },
+
+ bug1 : function(){
+ if(lollipops.nbrOwned >= 1000000){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 1000000);
+ switch(random.getRandomIntUpTo(3)){
+ case 0:
+ chocolateBars.setNbrOwned(chocolateBars.nbrOwned + 1);
+ htmlInteraction.setInnerHtml("computer_comment_1", "You found 1 chocolate bar !!");
+ break;
+ case 1:
+ chocolateBars.setNbrOwned(chocolateBars.nbrOwned + 2);
+ htmlInteraction.setInnerHtml("computer_comment_1", "You found 2 chocolate bars !!! \\o/");
+ break;
+ case 2:
+ chocolateBars.setNbrOwned(chocolateBars.nbrOwned + 3);
+ htmlInteraction.setInnerHtml("computer_comment_1", "You found 3 chocolate bars !!!!! \\o/ \\o/ \\o/ \\o/");
+ break;
+ case 3:
+ htmlInteraction.setInnerHtml("computer_comment_1", "There's a bug with the bug, it didn't worked :/");
+ break;
+ }
+ }
+ },
+
+ bug2 : function(){
+ var rndrnd;
+
+ if(lollipops.nbrOwned >= 10000000){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 10000000);
+ switch(random.getRandomIntUpTo(2)){
+ case 0:
+ candies.setNbrOwned(candies.nbrOwned + candies.nbrThrown);
+ htmlInteraction.setInnerHtml("computer_comment_2", "You picked up all candies you have thrown on the floor. (" + candies.nbrThrown + ")");
+ candies.setNbrThrown(0);
+ break;
+ case 1:
+ rndrnd = 2 + random.getRandomIntUpTo(50000000);
+ candies.setNbrOwned(candies.nbrOwned + rndrnd);
+ htmlInteraction.setInnerHtml("computer_comment_2", "You met " + random.pickRandomly(["an architect", "a fireman", "a butcher", "an electrician", "a writer", "a student", "a farmer", "a shoemaker", "a monk", "a journalist", "a reporter", "a priest", "a translator", "a vet"]) + ". He gave you " + rndrnd + " candies !");
+ break;
+ case 2:
+ farm.setMaxLollipopsPerDay(864000000);
+ htmlInteraction.showButton("computer_note");
+ htmlInteraction.setInnerHtml("computer_comment_2", "The production limit of your lollipop farm has increased ! (*)");
+ break;
+ }
+ }
+ },
+
+ bug3 : function(){
+ if(lollipops.nbrOwned >= 100000000){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 100000000);
+ switch(random.getRandomIntUpTo(2)){
+ case 0:
+ if(sword.name != "Sword of Liflamesummoning" && sword.name != "Sword of Randomness"){
+ sword.setName("Sword of Liflamesummoning");
+ htmlInteraction.setInnerHtml("computer_comment_3", "You found a new sword : the Sword of Liflamesummoning !");
+ }
+ else{
+ htmlInteraction.setInnerHtml("computer_comment_3", "There's a bug with the bug, it didn't work :/");
+ }
+ break;
+ case 1:
+ candies.setNbrOwned(candies.nbrOwned * 3);
+ htmlInteraction.setInnerHtml("computer_comment_3", "Your candies were multiplied by 3 !");
+ break;
+ case 2:
+ if(sword.specialSword == true){
+ if(random.oneChanceOutOf(6)){
+ sword.setSpecialPower(sword.specialPower - 3);
+ htmlInteraction.setInnerHtml("computer_comment_3", "Your sword lost 3 levels.");
+ inventory.updateOnPage();
+ }
+ else{
+ sword.setSpecialPower(sword.specialPower + 1);
+ htmlInteraction.setInnerHtml("computer_comment_3", "The level of your sword increased by 1 !");
+ inventory.updateOnPage();
+ }
+ }
+ else{
+ htmlInteraction.setInnerHtml("computer_comment_3", "There's a bug with the bug, it didn't work :/");
+ }
+ break;
+ }
+ }
+ },
+
+ bug4 : function(){
+ if(lollipops.nbrOwned >= 1000000000){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 1000000000);
+ htmlInteraction.setInnerHtml("computer_comment_4", "Fake bug ! I guess you'll need 10000 mpl :)");
+ }
+ },
+
+ bug5: function(){
+ if(lollipops.nbrOwned >= 10000000000){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 10000000000);
+ switch(random.getRandomIntUpTo(1)){
+ case 0:
+ if(land.ponyTime == false){
+ land.ponyTime = true;
+ htmlInteraction.setInnerHtml("computer_comment_5", "It's pony time !! Everyone is a pony now ! (*)");
+ htmlInteraction.showButton("computer_note");
+ }
+ else{
+ htmlInteraction.setInnerHtml("computer_comment_5", "There's a bug with the bug, it didn't work :/");
+ }
+ break;
+ case 1:
+ if(sword.name != "Sword of Randomness"){
+ sword.setName("Sword of Randomness");
+ htmlInteraction.setInnerHtml("computer_comment_5", "You found a new sword : the Sword of Randomness !");
+ }
+ else{
+ htmlInteraction.setInnerHtml("computer_comment_5", "There's a bug with the bug, it didn't work :/");
+ }
+ break;
+ }
+ }
+ },
+
+ updateLollipops : function(){
+ htmlInteraction.setInnerHtml("computer_lollipops", Math.floor(lollipops.nbrOwned/100000)/10);
+ },
+
+};
diff --git a/static/candies/scripts/cowLevel.js b/static/candies/scripts/cowLevel.js
new file mode 100755
index 00000000..7607036c
--- /dev/null
+++ b/static/candies/scripts/cowLevel.js
@@ -0,0 +1,85 @@
+var cowLevel = {
+
+ // Variables
+ size : 72,
+
+ // Functions
+ onload : function(){
+ land.addLand("cowLevel", this.size, -1, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ move : function(){
+ // Get the character index
+ var index = quest.getCharacterIndex();
+
+ // Iterate over all things
+ for(var i = 0; i < this.size; i++){
+ // If it's a cow
+ if(quest.things[i].text == "COW"){
+ // We make it move if possible (if it is too close from the player we force it moving to the left)
+ if(random.flipACoin() && Math.abs(index - i) > 5 && i < this.size - 1){
+ // If we can move it to the right
+ if(quest.things[i+1].type == "none"){
+ // We move it to the right
+ quest.things[i+1] = quest.things[i];
+ quest.things[i] = quest.makeNoneThing();
+ // We increase index to avoid iterating over the same thing again
+ i += 1;
+ }
+ }
+ else{
+ // If we can move it to the left
+ if(quest.things[i-1].type == "none"){
+ // We move it to the left
+ quest.things[i-1] = quest.things[i];
+ quest.things[i] = quest.makeNoneThing();
+ }
+ }
+ }
+ }
+ },
+
+ load : function(){
+ // Add the cow king
+ quest.things[5 + random.getRandomIntUpTo(this.size - 6)] = this.makeCowKing();
+
+ // Add cows
+ for(var i = 1; i < this.size - 1; i++){
+ if(quest.things[i].type == "none"){
+ if(random.flipACoin()){
+ quest.things[i] = this.makeCow();
+ }
+ }
+ }
+ },
+
+ getText : function(){
+ var text = " \"The cow level\"\n\n\n";
+
+ text += " ";
+ for(var i = 0; i < 18; i++){
+ text += quest.things[i].text;
+ }
+
+ text += "\n\n ";
+ for(var i = 18; i < 42; i++){
+ text += quest.things[i].text;
+ }
+
+ text += "\n\n";
+ for(var i = 42; i < this.size; i++){
+ text += quest.things[i].text;
+ }
+
+ return text;
+ },
+
+ makeCow : function(){
+ return land.createMob("COW", 12, 12, "horns", "A cow ! Mooooo !", [drops.createDrop("candies", 100)]);
+ },
+
+ makeCowKing : function(){
+ return land.createMob("COW", 180, 180, "horns", "The cow king ! It looks like a normal cow, but it isn't...", [drops.createDrop("candies", 1000), drops.createDrop("object", "hornOfPlenty", true)]);
+ }
+
+};
diff --git a/static/candies/scripts/damage.js b/static/candies/scripts/damage.js
new file mode 100755
index 00000000..9bfa4f47
--- /dev/null
+++ b/static/candies/scripts/damage.js
@@ -0,0 +1,169 @@
+var damage = {
+
+ getWeaponDamage : function(weapon){
+ switch(weapon){
+ // Us
+ case "none": return 0; break;
+ case "wooden sword": return 1; break;
+ case "copper sword": return 2; break;
+ case "iron sword": return 3; break;
+ case "silver sword": return 4; break;
+ case "diamond sword": return 5; break;
+ case "candy diamond sword": return 7; break;
+ case "polished candy diamond sword": return 10; break;
+ case "chocolate sword": return 12; break;
+ case "sharp chocolate sword": return 14; break;
+ case "Sword of Life": return 14; break;
+ case "Sword of Flames":
+ if(random.oneChanceOutOf(3)){
+ return 16 + Math.floor(sword.specialPower/2) + sword.specialPower*2;
+ }
+ else{
+ return 16 + Math.floor(sword.specialPower/2);
+ }
+ break;
+ case "Sword of Summoning": return 14; break;
+ case "Sword of Liflamesummoning": return 16 + sword.specialPower*5; break;
+ case "Sword of Randomness":
+ var index = quest.getCharacterIndex();
+ switch(random.getRandomIntUpTo(4)){
+ case 0: quest.things[index].text = " "; break;
+ case 1: quest.things[index].text = "___"; break;
+ case 2: quest.things[index].text = "r" + random.pickRandomly(["a", "p", "^", "'", "-", "+", "n", "m", "s", "o", ","]) + "r"; break;
+ case 3: quest.things[index].hp = Math.floor(quest.things[index].hp * random.getRandomFloat() * 2); break;
+ case 4: quest.things[index].hp = Math.floor(quest.things[index].max_hp * random.getRandomFloat() * 2); break;
+ }
+ return random.getRandomIntUpTo(sword.specialPower*114);
+ break;
+ // Traps
+ case "powerful explosion": return 100; break;
+ // Clone
+ case "cloned sword": return 12; break;
+ // Invocations
+ case "its whole body": return 5; break;
+ case "bludgeon": return 6; break;
+ case "various bones": return 7; break;
+ case "fangs": return 11; break;
+ case "rock": return 7; break;
+ case "fire": return 14; break;
+ case "exploding candies":
+ return 8 + Math.floor(sword.specialPower/2);
+ break;
+ // Peaceful forst
+ case "hooves": return 1; break;
+ // Mount Goblin
+ case "claws": return 1; break;
+ case "dagger": return 2; break;
+ // Underwater cave
+ case "fins": return 2; break;
+ case "tentacles": return 1 + random.getRandomIntUpTo(5); break;
+ case "giant tail": return 8; break;
+ case "electric tail": return 9 + random.getRandomIntUpTo(2); break;
+ // Castle's entrance
+ case "spear": return 7; break;
+ case "sharp sword": return 10; break;
+ // Castle's stairs
+ case "magic staff": return 6; break;
+ case "damaged sword": return 5; break;
+ // Castle's keep
+ case "horn": return 9; break;
+ case "horns": return 7; break;
+ case "foots and tail": return 7; break;
+ case "giant beak": return 7; break;
+ case "its fists": return 6; break;
+ case "its teeth": return 4; break;
+ case "spiky tail": return 10; break;
+ case "cursed sword": return 3 + random.getRandomIntUpTo(20); break;
+ case "itself": return 45; break;
+ case "sharp teeth": return 16; break;
+ case "magical horn": return 12; break;
+ case "enormous fist":
+ if(random.oneChanceOutOf(3)){
+ return 20;
+ }
+ return 0;
+ break;
+ case "flames": return 40; break;
+ // Cow level
+ case "horns": return 7; break;
+ // Desert
+ case "cactus thorns": return 4; break;
+ // Hell
+ case "religion": return 80; break;
+ case "demon claws": return 40; break;
+ case "spikes": return 15; break;
+ case "?": return 50; break;
+ // Chuck norris
+ case "Chuck Norris": return random.getRandomIntUpTo(chuckNorris.timeSpent*8); break;
+ // Developper's garden
+ case "ultra plasma gun": return 8; break;
+ // Developper's computer
+ case "bugs": return Math.floor(quest.getCharacterMaxHp()/4) + 5; break;
+ }
+
+ return 0;
+ },
+
+ makeTwoQuestThingsFighting : function(i, j){
+ var theFirstIsTheCharacter = false; // True if the first of the fighting things is the character
+ var howManyDamage = 0; // Used to calculate some stuff
+
+ // If the first thing is the character
+ if(quest.things[i].type == "character"){
+ theFirstIsTheCharacter = true;
+ }
+ // If the second thing is the character
+ else if(quest.things[j].type == "character"){
+ // Then it's the first one in fact :)
+ var temp = i;
+ i = j;
+ j = i;
+ theFirstIsTheCharacter = true;
+ }
+
+ // The second thing get hit by the first
+ quest.things[j].hp -= this.getWeaponDamage(quest.things[i].weapon);
+
+ // If the first isn't the character
+ if(theFirstIsTheCharacter == false){
+ quest.things[i].hp -= this.getWeaponDamage(quest.things[j].weapon); // The first thing get hit by the second one
+ }
+ // Else, the first is the character
+ else{
+ howManyDamage = this.getWeaponDamage(quest.things[j].weapon); // We store the damage the mob should do to us
+ // If we have a plate armour
+ if(objects.list.plateArmour.have){
+ howManyDamage -= 3; // We reduce the damage
+ }
+ // If we are a turtle
+ if(quest.turtle){
+ howManyDamage = Math.floor(howManyDamage/2);
+ }
+ // Spectral magic bonus (not influenced by the plate armour or the turtle state !)
+ if(quest.things[j].weapon == "spectral magic"){
+ howManyDamage = Math.ceil(quest.things[i].hp/2); // The damage is now half the life of the player
+ }
+ // If we are invincible
+ if(quest.invulnerability){
+ howManyDamage = 0; // No damage
+ }
+ if(howManyDamage > 0) quest.things[i].hp -= howManyDamage; // If we should still take damage, we take it
+ }
+
+ // Berserk bonuses : second hit
+ if(quest.berserk && theFirstIsTheCharacter) quest.things[j].hp -= this.getWeaponDamage(quest.things[i].weapon);
+
+ // We correct health points if they're < 0
+ if(quest.things[i].hp < 0) quest.things[i].hp = 0;
+ if(quest.things[j].hp < 0) quest.things[j].hp = 0;
+
+ // Yourself quest can surpass bonus
+ if(land.getLandIndexFromName("Yourself") == quest.currentLandIndex && yourself.canSurpass == true && theFirstIsTheCharacter == true){
+ if(quest.things[i].hp == 0){
+ quest.things[i].hp = 1;
+ yourself.end = true;
+ }
+ }
+ }
+
+}
diff --git a/static/candies/scripts/desert.js b/static/candies/scripts/desert.js
new file mode 100755
index 00000000..cd9a74c4
--- /dev/null
+++ b/static/candies/scripts/desert.js
@@ -0,0 +1,56 @@
+var desert = {
+
+ // Variables
+ size : 25,
+
+ // Functions
+ onload : function(){
+ land.addLand("desert", this.size, -1, this.load.bind(this), this.getText.bind(this));
+ },
+
+ load : function(){
+
+ },
+
+ getText : function(){
+ var lines = this.asciiDesert.slice(0);
+
+ for(var i = 0; i < this.size; i++){
+ if(quest.things[i].type == "character"){
+ if(i == 12) lines[12] = lines[12].replaceAt(i*3, quest.things[i].text[0]);
+ else if(i == 13) lines[12] = lines[12].replaceAt(i*3, quest.things[i].text[0]);
+ else if(i == 14) lines[12] = lines[12].replaceAt(i*3 + 1, quest.things[i].text[1]);
+ else if(i == 15) lines[12] = lines[12].replaceAt(i*3 + 1, quest.things[i].text[1] + quest.things[i].text[2]);
+ else if(i == 17) lines[12] = lines[12].replaceAt(i*3, quest.things[i].text[0] + quest.things[i].text[1]);
+ else if(i == 18 || i == 19) ;
+ else if(i == 20) lines[12] = lines[12].replaceAt(i*3 + 2, quest.things[i].text[2]);
+ else lines[12] = lines[12].replaceAt(i*3, quest.things[i].text);
+ }
+ }
+
+ return lines.join("");
+ },
+
+ // Ascii
+ asciiDesert :
+[
+" \"The desert\" \n",
+" \n",
+" \n",
+" _ _ \n",
+" / \\ _ / \\ _ \n",
+" , | | , / \\ , | | , / \\ \n",
+" ((_| |_)) , | | , ((_| |_)) , | | , \n",
+" `--, ,--` ((_| |_)) `--, ,--` ((_| |_)) \n",
+" | | `--, ,--` | | _ `--, ,--` \n",
+" | | | | | | _ / \\ | | \n",
+" `\"\"\"` | | `\"\"\"`/ \\ , | | , | | \n",
+" `\"\"\"` , | | , ((_| |_)) `\"\"\"` \n",
+" ((_| |_)) `--, ,--` \n",
+" `--, ,--` | | \n",
+" | | | | \n",
+" | | `\"\"\"` \n",
+" `\"\"\"` \n"
+]
+
+};
diff --git a/static/candies/scripts/developperComputer.js b/static/candies/scripts/developperComputer.js
new file mode 100755
index 00000000..ba124f82
--- /dev/null
+++ b/static/candies/scripts/developperComputer.js
@@ -0,0 +1,102 @@
+var developperComputer = {
+
+ // Variables
+ size : 22,
+ won : false,
+ letter : 0,
+
+ // Functions
+ onload : function(){
+ land.addLand("Developper's computer", this.size, 11, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ setWon : function(value){
+ this.won = value;
+ if(this.won == true){
+ tabs.enable(4);
+ htmlInteraction.showButton("tab_computer");
+ }
+ inventory.updateOnPage();
+ },
+
+ move : function(){
+
+ },
+
+ useLetter : function(){
+ var index = quest.getCharacterIndex();
+
+ if(quest.weAreQuestingRightNow && land.getLandIndexFromName("Developper's computer") == quest.currentLandIndex){
+ if(quest.things[this.size-1].text == "DEV" && index == this.size-2){
+ quest.things[this.size-1].hp = 0;
+ }
+ }
+ },
+
+ load : function(){
+ // Add the dev
+ quest.things[21] = this.makeDev();
+
+ // Add bugs
+ for(var i = 1; i <= 20; i++){
+ if(random.flipACoin()){
+ quest.things[i] = this.makeBug();
+ }
+ }
+
+ // Choose letter
+ this.letter = 65 + random.getRandomIntUpTo(25);
+ },
+
+ getText : function(){
+ var textBefore = "";
+ var lines = this.asciiComputer.slice(0);
+ var x = 0;
+ var y = 0;
+ var pos = 0;
+ var index = quest.getCharacterIndex();
+
+ if(index == this.size-2) textBefore = "You must press a certain key to kill the developper.\n\n";
+
+ for(var i = 0; i < 100; i++){
+ x = random.getRandomIntUpTo(65);
+ y = random.getRandomIntUpTo(9);
+ lines[y] = lines[y].replaceAt(x, random.pickRandomly(["$", "%", "*", ":", ";", ",", ".", "-", "+", "_", "-", "d", "n", "c"]));
+ }
+
+ // Add things
+ for(var i = 0; i < this.size; i++){
+ if(quest.things[i].type != "none"){
+ pos = random.getRandomIntUpTo(9);
+ lines[pos] = lines[pos].replaceAt(i*3, quest.things[i].text);
+ }
+ }
+
+ return textBefore + lines.join("");
+ },
+
+ makeBug : function(){
+ return land.createMob(random.pickRandomly(["B", "U", "G"]) + random.pickRandomly(["B", "U", "G"]) + random.pickRandomly(["B", "U", "G"]), 300 + random.getRandomIntUpTo(10000000), 300, random.pickRandomly(["itself", "religion", "flames", "sharp teeth", "cursed sword", "claws", "dagger", "fins", "hooves", "magic staff", "horn", "silver sword", "chocolate sword", "demon claws"]), "A bug !", [drops.createDrop("candies", 100000000)]);
+ },
+
+ makeDev : function(){
+ return land.createMob("DEV", 100000000000000, 100000000000000, "bugs", "The developper (hey, he made this game!)", [drops.createDrop("candies", 1000000)]);
+ },
+
+ // Ascii
+
+ asciiComputer :
+[
+" \n",
+" \n",
+" \n",
+" \n",
+" \n",
+" \n",
+" \n",
+" \n",
+" \n",
+" \n"
+]
+
+};
diff --git a/static/candies/scripts/developperGarden.js b/static/candies/scripts/developperGarden.js
new file mode 100755
index 00000000..573104cb
--- /dev/null
+++ b/static/candies/scripts/developperGarden.js
@@ -0,0 +1,89 @@
+var developperGarden = {
+
+ // Variables
+ size : 40,
+
+ // Functions
+ onload : function(){
+ land.addLand("Developper's garden", this.size, 9, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ move : function(){
+ var targetIndex = -1;
+
+ // We make the gnomes shooting
+ for(var i = 0; i < this.size; i++){
+ if(quest.things[i].text == "CGG"){
+ if(targetIndex != -1){ // If we have a target
+ quest.things[targetIndex].hp -= 30;
+ if(quest.things[targetIndex].hp <= 0){
+ if(quest.things[targetIndex].type != "character") quest.things[targetIndex] = quest.makeNoneThing();
+ else quest.things[targetIndex].hp = 1;
+ targetIndex = -1;
+ }
+ }
+ }
+ else if(quest.things[i].type != "none"){
+ targetIndex = i;
+ }
+ }
+
+ // Increase the time spent
+ this.timeSpent += 1;
+ },
+
+ load : function(){
+ // Add garden gnomes
+ quest.things[27] = this.makeCheatedGardenGnome();
+ quest.things[28] = this.makeCheatedGardenGnome();
+ if(random.flipACoin()) quest.things[29] = this.makeCheatedGardenGnome();
+ quest.things[30] = this.makeCheatedGardenGnome();
+ quest.things[31] = this.makeCheatedGardenGnome();
+ if(random.flipACoin()) quest.things[32] = this.makeCheatedGardenGnome();
+ quest.things[34] = this.makeCheatedGardenGnome();
+ quest.things[35] = this.makeCheatedGardenGnome();
+ quest.things[36] = this.makeCheatedGardenGnome();
+ quest.things[37] = this.makeCheatedGardenGnome();
+ quest.things[38] = this.makeCheatedGardenGnome();
+ if(random.flipACoin()) quest.things[39] = this.makeCheatedGardenGnome();
+ },
+
+ makeCheatedGardenGnome : function(){
+ return land.createMob("CGG", 70, 70, "ultra plasma gun", "A cheated garden gnome. Since when garden gnomes have guns like that ?", []);
+ },
+
+ getText : function(){
+ // Create the text
+ var lines = this.asciiGarden.slice(0);
+
+ // Add things
+ for(var i = 0; i < this.size; i++){
+ if(quest.things[i].type != "none"){
+ lines[13] = lines[13].replaceAt(i*3, quest.things[i].text);
+ }
+ }
+
+ return lines.join("");
+ },
+
+ // Ascii
+ asciiGarden :
+[
+" , \n",
+" /\\^/`\\ \n",
+" | \\/ | \n",
+" | | | \n",
+" _ _ \\ \\ / \n",
+" _{ ' }_ '\\\\//' \n",
+" _ { `.!.` } || \n",
+" _(_)_ wWWWw ',_/Y\\_,' || \n",
+" (_)@(_) (___) {_,_} || \n",
+" (_)\\ Y | vVVVv |\\ || |\\ \n",
+" |/ \\|/ (\\| (___) | | || | | \n",
+" \\| |/ \\| /) Y | | || / / \n",
+" | \\| |// (\\|/) \\ \\||/ / \n",
+" \\\\\\|// \\\\|// |/ \\|/ `\\\\//` \n",
+"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
+]
+
+};
diff --git a/static/candies/scripts/developperMoat.js b/static/candies/scripts/developperMoat.js
new file mode 100755
index 00000000..d3935e1f
--- /dev/null
+++ b/static/candies/scripts/developperMoat.js
@@ -0,0 +1,74 @@
+var developperMoat = {
+
+ // Variables
+ size : 22,
+ platformPosition : 0,
+ timeSpent : 0,
+
+ // Functions
+ onload : function(){
+ land.addLand("Developper's moat", this.size, 10, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ move : function(){
+ // Get the character's index
+ var index = quest.getCharacterIndex();
+
+ // If the character is above where the platform moves
+ if(index > 5 && index < 18){
+ // If the character isn't on the platform
+ if(index > 6 + this.platformPosition + 1 || index < 6 + this.platformPosition){
+ quest.escaping = true;
+ }
+ }
+
+ // Increase the platform position
+ if(this.timeSpent > 5){
+ if(this.platformPosition < 10) this.platformPosition = Math.floor((this.timeSpent - 5) / 3);
+ }
+
+ // Increase the time spent
+ this.timeSpent += 1;
+ },
+
+ load : function(){
+ this.platformPosition = 0;
+ this.timeSpent = 0;
+ },
+
+ getText : function(){
+ var lines = this.asciiMoat.slice(0);
+
+ // Add the platform
+ lines[3] = lines[3].replaceAt(18 + this.platformPosition*3, "______");
+ lines[4] = lines[4].replaceAt(18 + this.platformPosition*3, "\\|__|/");
+
+ // Add things
+ for(var i = 0; i < this.size; i++){
+ if(quest.things[i].type == "character"){
+ lines[3] = lines[3].replaceAt(i*3, quest.things[i].text);
+ }
+ }
+
+ return lines.join("");
+ },
+
+ // Ascii
+
+ asciiMoat :
+[
+" \n",
+" \n",
+" \n",
+"__________________ ____________\n",
+" \\, ._/ /\n",
+" \\, / \\ \\\n",
+" )_, (__ _\\\n",
+" / _\\ / ./ /\n",
+" \\, | | / /\n",
+" / _/ \\ / (\n",
+" _,| /_\n",
+" \\ |"
+]
+
+};
diff --git a/static/candies/scripts/donotopen.js b/static/candies/scripts/donotopen.js
new file mode 100755
index 00000000..6e44259a
--- /dev/null
+++ b/static/candies/scripts/donotopen.js
@@ -0,0 +1,198 @@
+var load = {
+
+ loadSave : function(){
+ // buttons.js
+ // The only variable says if the home buttons are disabled or not
+ // We don't have to save that since the button to make a save is itself a home button
+
+ // sword.js \*/ must be loaded before forge.js, since the forge speech may be based on the sword name.., must be loaded before candies.js too \*/
+ sword.setName("wooden sword"); // sword.name string 50
+ sword.setSpecialSword(false); // sword.specialSword bool
+ sword.setSpecialPower(1); // sword.specialPower int
+ // summonList : mobs to summon are added in the onload function, so we don't have to save it
+
+ // candies.js
+ candies.setNbrOwned(12000000); // candies.nbrOwned int
+ candies.setNbrThrown(60); // candies.nbrThrown int
+ candies.setNbrEaten(107000000000); // candies.nbrEaten int
+ candies.setNbrTotal(500000000000000); // candies.nbrTotal int
+ candies.setCandiesPerSecond(1); // candies.candiesPerSecond int
+
+ // candiesConverter.js
+ candiesConverter.setActivated(false); // candiesConverter.activated bool
+
+ // castleEntrance.js
+ // The variables are only used while questing, so we don't have to save them
+
+ // cauldron.js
+ cauldron.setBookPage(0); // cauldron.bookPage int
+ cauldron.setCandiesInTheCauldron(0); // cauldron.candiesInTheCauldron int
+ cauldron.setLollipopsInTheCauldron(0); // cauldron.lollipopsInTheCauldron int
+
+ // chocolateBars.js
+ chocolateBars.setNbrOwned(1); // chocolateBars.nbrOwned int
+
+ // damage.js
+ // No variables, nothing to save
+
+ // drops.js
+ // No variables, nothing to save
+
+ // farm.js
+ farm.setLollipopsPlanted(120); // farm.lollipopsPlanted int
+ // farm.productionDelayType : no save, it's calculated
+ // farm.lollipopsPerDay : no save, it's calculated
+ // farm.lollipopsProduction : no save, it's calculated
+ // farm.maxLollipopsPerDay : constant, no save
+ // farm.flagsList : constant, no save
+ farm.setCurrentFlagIndex(5); // farm.currentFlagIndex int
+ farm.setPlantingButtonsStep(4); // farm.plantingButtonsStep int
+
+ // forge.js
+ // forge.shown : can't be true when we save, so we don't save it
+ forge.setStep(0); // forge.step
+ // forge.speech : we don't save, since it's set by the stepStep function
+
+ // htmlInteraction.js
+ // No variables, nothing to save
+
+ // shop.js
+ shop.setBuy10LollipopsButtonShown(false); // shop.buy10LollipopsButtonShown bool
+ shop.setShown(true); // shop.shown bool
+ shop.setTicklingStep(0); // shop.ticklingStep int
+ shop.setClickingOnLollipopStep(11); // shop.clickingOnLollipopStep int
+ // shop.oneLollipopPrice : calculated by the clickingOnLollipopStep, so we don't save
+ // shop.tenLollipopsPrice : same as above
+ // shop.currentSwordButtonId : calculated by showProduct, so we don't save
+ // shop.currentSwordPrice : same as above
+
+ // hut.js
+ // hut.shown : can't be true when we save, so we don't save it
+ hut.setStep(0); // hut.step int
+ hut.setSpeech(""); // hut.speech string 1000
+
+ // inventory.js
+ inventory.setMagicianHatLetter(" m\n"); // inventory.magicianHatLetter string 50
+
+ // jquery.tabify.js
+ // nothing to save
+
+ // land
+ // land.list : this list is constant, so no need to save
+
+ // lollipops.js
+ lollipops.setNbrOwned(5000000000000); // lollipops.nbrOwned int
+ lollipops.setNbrInStock(24); // lollipops.nbrInStock int
+ lollipops.setNbrBought(0); // lollipops.nbrBought int
+ // lollipops.stockShortage : calculated by setNbrInStock, so no need to save
+
+ // main.js
+ main.setNbrOfSecondsSinceLastMinInterval(0); // main.nbrOfSecondsSinceLastMinInterval int
+ main.setNbrOfSecondsSinceLastHourInterval(0); // main.nbrOfSecondsSinceLastHourInterval int
+ main.setNbrOfSecondsSinceLastDayInterval(0); // main.nbrOfSecondsSinceLastDayInterval int
+
+ // mountGoblin.js
+ mountGoblin.setBasicChestProbability(100); // mountGoblin.basicChestProbability int
+
+ // peacefulForest.js
+ peacefulForest.setBasicChestProbability(100); // peacefulForest.basicChestProbability int
+ peacefulForest.setPoniesEncountered(0); // peacefulForest.poniesEncountered int
+
+ // objects.js
+ objects.setHaveObject("key", true); // objects.list.key.have bool
+ objects.setHaveObject("hutMap", true); // idem
+ objects.setHaveObject("wellMap", true); // idem
+ objects.setHaveObject("swampMap", true); // idem
+ objects.setHaveObject("boots", true); // idem
+ objects.setHaveObject("magicianHat", true); // idem
+ objects.setHaveObject("pinkRing", true); // idem
+ objects.setHaveObject("forgeMap", true); // idem
+ objects.setHaveObject("candiesConverter", true); // idem
+ objects.setHaveObject("plateArmour", true); // idem
+ objects.setHaveObject("cauldron", true); // idem
+ objects.setHaveObject("magicalHorn", true); // idem
+ objects.setHaveObject("hornOfPlenty", true); // idem
+ objects.setHaveObject("oldAmulet", true); // idem
+
+ // potions.js
+ // potions.list : potions are added to the list in the onload function, no need to save most variables
+ // the only variables we need to save is the shown one and the nbrOwned one
+ potions.setPotionShown(potions.list.health, true); // potions.list.health.shown bool
+ potions.setPotionShown(potions.list.escape, true); // idem
+ potions.setPotionShown(potions.list.berserk, true); // idem
+ potions.setPotionShown(potions.list.fireScroll, true); // idem
+ potions.setPotionShown(potions.list.acidRainScroll, true); // idem
+ potions.setPotionShown(potions.list.teleportScroll, true); // idem
+ potions.setPotionShown(potions.list.earthquakeScroll, true); // idem
+ potions.setPotionShown(potions.list.impInvocationScroll, true); // idem
+ potions.setPotionShown(potions.list.majorHealth, true); // idem
+ potions.setPotionShown(potions.list.invulnerability, true); // idem
+ potions.setPotionShown(potions.list.turtle, true); // idem
+ potions.setPotionShown(potions.list.jelly, true); // idem
+ potions.setPotionShown(potions.list.seed, true); // idem
+ potions.setPotionShown(potions.list.cloning, true); // idem
+ potions.setPotionShown(potions.list.superman, true); // idem
+ potions.setPotionShown(potions.list.gmooh, true); // idem
+
+ potions.setPotionNbrOwned(potions.list.health, 10); // potions.list.health.nbrOwned int
+ potions.setPotionNbrOwned(potions.list.escape, 10); // idem
+ potions.setPotionNbrOwned(potions.list.berserk, 110); // idem
+ potions.setPotionNbrOwned(potions.list.fireScroll, 42); // idem
+ potions.setPotionNbrOwned(potions.list.acidRainScroll, 10); // idem
+ potions.setPotionNbrOwned(potions.list.teleportScroll, 250); // idem
+ potions.setPotionNbrOwned(potions.list.earthquakeScroll, 50); // idem
+ potions.setPotionNbrOwned(potions.list.impInvocationScroll, 10); // idem
+ potions.setPotionNbrOwned(potions.list.majorHealth, 10); // idem
+ potions.setPotionNbrOwned(potions.list.invulnerability, 1337); // idem
+ potions.setPotionNbrOwned(potions.list.turtle, 17); // idem
+ potions.setPotionNbrOwned(potions.list.jelly, 17000); // idem
+ potions.setPotionNbrOwned(potions.list.seed, 15); // idem
+ potions.setPotionNbrOwned(potions.list.cloning, 15); // idem
+ potions.setPotionNbrOwned(potions.list.superman, 15); // idem
+ potions.setPotionNbrOwned(potions.list.gmooh, 80); // idem
+
+ potions.updateOnPage();
+
+ // quest.js
+ quest.setMaxLandOrder(25); // quest.maxLandOrder, must be saved because it indicates the lands we have unlocked for the moment int
+ quest.setTiredTime(0); // quest.tiredTime, must be saved because we may do a quest, have a long tired time, and save before the tired time ends int
+ // All other variables should not be saved because they only describe the internal states of the quest, we we can't save while questing !
+
+ // random.js
+ // nothing to save
+
+ // speech.js
+ // nothing to save
+
+ // spells.js
+ // spells.list : spells are added to the list in the onload function, no need to save
+ spells.setFasterCandiesFibo(1, 2); // spells.fasterCandiesFiboPrev && spells.fasterCandiesFiboCurr int && int
+
+ // status.js
+ // nothing to save
+
+ // swamp.js
+ // swamp.shown : can't be true when we save, so we don't save it
+ swamp.setStep(0); // swamp.step int
+
+ // tabs.js
+ tabs.setAnimation("none"); // tabs.animation string 50
+
+ // underwaterCave.js
+ // nothing to save
+
+ // wishingWell.js
+ // wishingWell.shown : can't be true when we save, so we don't save it
+ wishingWell.setSpeech(""); // wishingWell.speech string 1000
+ wishingWell.setStep(0); // wishingWell.step int
+
+ // yourself.js
+ yourself.setCanSurpass(true); // yourself.canSurpass bool
+
+ // castleEntrance.js
+ // nothing to save, all the variables are internal states of the quest
+
+ developperComputer.setWon(false);
+}
+
+};
diff --git a/static/candies/scripts/drops.js b/static/candies/scripts/drops.js
new file mode 100755
index 00000000..96273a91
--- /dev/null
+++ b/static/candies/scripts/drops.js
@@ -0,0 +1,58 @@
+var drops = {
+
+ createDrop : function(type, param1, param2){
+ return {type:type, param1:param1, param2:param2};
+ },
+
+ getText : function(){
+ var text = "";
+
+ // Candies found
+ if(quest.candiesFound != 1) text += "You found " + quest.candiesFound + " candies.";
+ else text += "You found 1 candy.";
+
+ // Objects found
+ for(obj in objects.list){
+ if(objects.list[obj].found){
+ text += "\nYou found " + objects.list[obj].text + ".";
+ }
+ }
+
+ // Notice
+ text += "\n\nThings found will be yours only if you finish the quest without dying.";
+
+ return text;
+ },
+
+ gainDrops : function(){
+ // Gain the candies
+ candies.setNbrOwned(candies.nbrOwned + quest.candiesFound);
+
+ // Gain the objects
+ for(obj in objects.list){
+ if(objects.list[obj].found){ // If we found this object but didn't have it already
+ objects.setHaveObject(obj, true);
+ }
+ }
+ },
+
+ getAllDropsFromList : function(list){
+ for(var i = 0; i < list.length; i++){
+ switch(list[i].type){
+ case "candies":
+ quest.setCandiesFound(quest.candiesFound + list[i].param1);
+ break;
+ case "object":
+ if(list[i].param2 == true) this.foundObject(list[i].param1);
+ break;
+ }
+ }
+ },
+
+ foundObject : function(name){
+ // If we don't already have this object, then we just found it !
+ if(objects.list[name].have == false) objects.list[name].found = true;
+ }
+
+};
+
diff --git a/static/candies/scripts/farm.js b/static/candies/scripts/farm.js
new file mode 100755
index 00000000..ee8d4460
--- /dev/null
+++ b/static/candies/scripts/farm.js
@@ -0,0 +1,125 @@
+var farm = {
+
+ // Variables
+ lollipopsPlanted : 0, // The number of lollipops planted in the farm
+ productionDelayType : "none", // On which delay does the farm product lollipops (day, hour, min, sec...)
+ lollipopsPerDay : 0, // How many lollipops the farm produce every day
+ lollipopsProduction : 0, // How many lollipops the farm produce every day, hour, min, sec.. depending on the production delay type
+ maxLollipopsPerDay : 8640000, // = 100/sec
+ flagsList : [" ~ ", " * ", "cnd", " ! ", " + ", " ? ", "/|\\"], // List of ascii flags which can appear on the farm
+ currentFlagIndex : 0, // Index in the list of the current flag shown
+ plantingButtonsStep : 0, // Step of the lollipops planting buttons : (= which buttons are shown, 1000, 100.. ?)
+
+ // Functions
+ calculateLollipopsPerDay : function(){
+ if(this.lollipopsPlanted <= 293){ // sqrt(86400) = 293
+ this.lollipopsPerDay = Math.pow(this.lollipopsPlanted, 2); // 293 will give 85849
+ }
+ else{ // When we're counting in lp/sec, this function is used instead of the other one. It will stabilize the curve.
+ var prod = (this.lollipopsPlanted - 122) * 500; // 194 will give 86000
+ if(prod < this.maxLollipopsPerDay) this.lollipopsPerDay = prod;
+ else this.lollipopsPerDay = this.maxLollipopsPerDay;
+ }
+ },
+
+ setPlantingButtonsStep : function(value){
+ // Set the value
+ this.plantingButtonsStep = value;
+
+ // Update on page
+ switch(this.plantingButtonsStep){
+ case 1:
+ htmlInteraction.setInnerHtml("lp_buttons", "");
+ break;
+ case 2:
+ htmlInteraction.setInnerHtml("lp_buttons", "Plant lollipops");
+ break;
+ case 3:
+ htmlInteraction.setInnerHtml("lp_buttons", "Plant lollipops");
+ break;
+ case 4:
+ htmlInteraction.setInnerHtml("lp_buttons", "Plant lollipops");
+ break;
+ }
+
+ // Check the buttons
+ buttons.checkLollipopsPlantingButtons();
+ },
+
+ clickedOnTheBigLollipop : function(){
+ // Increment the current flag index
+ this.setCurrentFlagIndex(this.currentFlagIndex + 1);
+ },
+
+ setCurrentFlagIndex : function(value){
+ // Set the new value and correct it if incorrect
+ this.currentFlagIndex = value;
+ if(this.currentFlagIndex >= this.flagsList.length || this.currentFlagIndex < 0) this.currentFlagIndex = 0;
+
+ // Update on the page
+ htmlInteraction.setInnerHtml("farm_big_lollipop", this.flagsList[this.currentFlagIndex]);
+ },
+
+ checkVisibility : function(){
+ if(objects.list.key.have){
+ htmlInteraction.setElementVisibility("farm", true);
+ }
+ },
+
+ plantLollipops : function(number){
+ if(lollipops.nbrOwned >= number){
+ lollipops.setNbrOwned(lollipops.nbrOwned - number);
+ this.setLollipopsPlanted(this.lollipopsPlanted + number);
+ }
+ },
+
+ setLollipopsPlanted : function(value){
+ // We change the value
+ this.lollipopsPlanted = value;
+
+ // We update on page
+ htmlInteraction.setInnerHtml("lp_planted", "Lollipops planted: " + numberWithCommas(this.lollipopsPlanted) + "");
+
+ // We re calculate stuff
+ this.calculateLollipopsPerDay();
+ this.calculateLollipopsProductionFromLollipopsPerDay();
+ },
+
+ calculateLollipopsProductionFromLollipopsPerDay : function(){
+ if(this.lollipopsPerDay < 24){
+ this.setProductionDelayType("day");
+ this.setLollipopsProduction(Math.floor(this.lollipopsPerDay));
+ }
+ else if(this.lollipopsPerDay < 1440){
+ this.setProductionDelayType("hour");
+ this.setLollipopsProduction(Math.floor(this.lollipopsPerDay/24));
+ }
+ else if(this.lollipopsPerDay < 86400){
+ this.setProductionDelayType("min");
+ this.setLollipopsProduction(Math.floor(this.lollipopsPerDay/1440));
+ }
+ else{
+ this.setProductionDelayType("sec");
+ this.setLollipopsProduction(Math.floor(this.lollipopsPerDay/86400));
+ }
+ },
+
+ setProductionDelayType: function(value){
+ this.productionDelayType = value;
+ },
+
+ setLollipopsProduction : function(value){
+ this.lollipopsProduction = value;
+ htmlInteraction.setInnerHtml("lp_production", "Production rate: " + numberWithCommas(this.lollipopsProduction) + " lollipops/" + this.productionDelayType + "");
+ },
+
+ setMaxLollipopsPerDay : function(value){
+ // We set the max lollipops per day
+ this.maxLollipopsPerDay = value;
+
+ // We re calculate stuff
+ this.calculateLollipopsPerDay();
+ this.calculateLollipopsProductionFromLollipopsPerDay();
+ }
+
+};
diff --git a/static/candies/scripts/forge.js b/static/candies/scripts/forge.js
new file mode 100755
index 00000000..03943b13
--- /dev/null
+++ b/static/candies/scripts/forge.js
@@ -0,0 +1,100 @@
+var forge = {
+
+ // Variables
+
+ shown : false,
+ step : 0,
+ speech : "There's an anvil here.",
+
+ // Functions
+
+ updateOnPage : function(){
+ var text = "";
+
+ // The anvil
+ text += "\
+ .-------..___\n\
+ \'-._ :_.-\'\n\
+ .- ) _ ( --.\n\
+ : \'-\' \'-\' ;.\n\
+ /\'-.._____.-\' |\n\
+ | | \\ |\n\
+ \\ | / \\\n\
+ | \\ )_.-\'\n\
+ \'-._/__..-\'\n\n"
+
+ // The speech
+ text += speech.makeSpeechFromText(this.speech, 23, "");
+
+ text += "\n\n";
+
+ // Buttons
+ switch(this.step){
+ case 0:
+ if(sword.name == "chocolate sword"){
+ text += "\n";
+ }
+ break;
+ case 1:
+ if(potions.list.health.shown)
+ text += "\n";
+ if(potions.list.fireScroll.shown)
+ text += "\n";
+ if(potions.list.impInvocationScroll.shown)
+ text += "\n";
+ break;
+ }
+
+ // The leave button
+ text += "\n";
+
+ htmlInteraction.setInnerHtml("map", text);
+
+ buttons.checkForge();
+ },
+
+ setStep : function(value){
+ // We change the value
+ this.step = value;
+
+ // We possibly change the speech depending on the new step
+ switch(this.step){
+ case 1:
+ this.speech = "You could enchant your sword using this anvil, but be careful : you can only enchant a sword once !";
+ break;
+ case 2:
+ // At this step, the speech is based on the sword name
+ switch(sword.name){
+ case "Sword of Flames":
+ this.speech = "You now have the Sword of Flames ! Your sword is covered by a permanent blaze, damaging your enemies more than ever.";
+ break;
+ case "Sword of Life":
+ this.speech = "You now have the Sword of Life ! This powerful charm will drain the life of your enemies to regain yours.";
+ break;
+ case "Sword of Summoning":
+ this.speech = "You now have the Sword of Summoning ! Your sword will sometimes spawn ally creatures in place of your dead enemies.";
+ break;
+ }
+ break;
+ }
+
+ // We update on page if the forge is shown
+ if(this.shown) this.updateOnPage();
+ },
+
+ enter : function(){
+ objects.leave();
+
+ this.shown = true;
+
+ this.updateOnPage();
+ },
+
+ leave : function(){
+ this.shown = false;
+
+ htmlInteraction.setInnerHtml("map", "");
+ //buttons.enableHomeButtons();
+ }
+
+};
diff --git a/static/candies/scripts/hell.js b/static/candies/scripts/hell.js
new file mode 100755
index 00000000..0717899f
--- /dev/null
+++ b/static/candies/scripts/hell.js
@@ -0,0 +1,414 @@
+var hell = {
+
+ // Variables
+
+ size : 45,
+ lavaLakeStep : 0,
+ buffers : [[], [], [], [], [], [], []], // The three things buffers
+ bufferPosition : 1, // On which buffer is the character (at first in the middle buffer)
+ timeSpent : 0, // Increase each cycle
+ addRockStep : 0,
+ monstersGap : 7, // Gap between the devil and appearing monsters
+ step : 0,
+
+ // Functions
+
+ onload : function(){
+ land.addLand("Hell", this.size, 6, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ move : function(){
+ // We increase the lava lake step
+ this.lavaLakeStep += 1;
+ if(this.lavaLakeStep == 12){
+ this.lavaLakeStep = 0;
+ }
+
+ // We make things move
+ for(var i = 0; i < 7; i++){
+ if(i != this.bufferPosition){
+ if(this.buffers[i][0].type == "mob") this.buffers[i][0] = quest.makeNoneThing();
+ for(var j = 1; j < this.size - 1; j++){
+ if(this.buffers[i][j].type == "mob" && this.buffers[i][j-1].type == "none" && this.buffers[i][j].text != " * " && this.buffers[i][j].text != "|-|"){
+ this.buffers[i][j-1] = this.buffers[i][j];
+ this.buffers[i][j] = quest.makeNoneThing();
+ }
+ }
+ // Clone
+ for(var j = this.size-2; j >= 0; j--){
+ if(this.buffers[i][j].text == "\\o/" && this.buffers[i][j].type == "ally" && this.buffers[i][j+1].type == "none" && this.buffers[i][j].text != " * " && this.buffers[i][j].text != "|-|"){
+ this.buffers[i][j+1] = this.buffers[i][j];
+ this.buffers[i][j] = quest.makeNoneThing();
+ }
+ }
+ }
+ else{
+ if(quest.things[0].type == "mob") quest.things[0] = quest.makeNoneThing();
+ for(var j = 1; j < this.size - 1; j++){
+ if(quest.things[j].type == "mob" && quest.things[j-1].type == "none" && quest.things[j].text != " * " && quest.things[j].text != "|-|"){
+ quest.things[j-1] = quest.things[j];
+ quest.things[j] = quest.makeNoneThing();
+ }
+ }
+ }
+ }
+
+ // We check the steps
+ switch(this.step){
+ case 0: this.checkStep1(); break;
+ case 1: this.checkStep2(); break;
+ case 2: this.checkStep3(); break;
+ case 3: this.checkStep4(); break;
+ }
+
+ // We add ennemies in the middle buffers
+ for(var i = 2; i < 5; i++){
+ if(i != this.bufferPosition && this.buffers[i][this.size-this.monstersGap].type == "none"){
+ this.buffers[i][this.size-this.monstersGap] = this.makeMiddleCreature();
+ }
+ else if(i == this.bufferPosition && quest.things[this.size-this.monstersGap].type == "none"){
+ quest.things[this.size-this.monstersGap] = this.makeMiddleCreature();
+ }
+ }
+
+ // Idem in the side buffers
+ for(var i = 0; i < 2; i++){
+ if(i != this.bufferPosition && this.buffers[i][this.size-this.monstersGap].type == "none"){
+ this.buffers[i][this.size-this.monstersGap] = this.makeSideCreature();
+ }
+ else if(i == this.bufferPosition && quest.things[this.size-this.monstersGap].type == "none"){
+ quest.things[this.size-this.monstersGap] = this.makeSideCreature();
+ }
+ }
+
+ for(var i = 5; i < 7; i++){
+ if(i != this.bufferPosition && this.buffers[i][this.size-this.monstersGap].type == "none"){
+ this.buffers[i][this.size-this.monstersGap] = this.makeSideCreature();
+ }
+ else if(i == this.bufferPosition && quest.things[this.size-this.monstersGap].type == "none"){
+ quest.things[this.size-this.monstersGap] = this.makeSideCreature();
+ }
+ }
+
+ // We increase the time spent
+ this.timeSpent += 1;
+ },
+
+ load : function(){
+ // We set the first buffer position
+ this.bufferPosition = 3;
+
+ // We fill buffers
+ for(var i = 0; i < 7; i++){
+ if(i != this.bufferPosition){
+ this.buffers[i] = quest.fillWithNoneThings();
+ }
+ }
+
+ // We add the devil
+ quest.things[this.size - 1] = this.makeDevil();
+
+ // We add first doors
+ quest.things[this.size - 4] = this.makeDoor();
+ for(var i = 0; i < 7; i++){
+ if(i != 3) this.buffers[i][this.size - 4] = this.makeDoor();
+ }
+
+ // We add second doors
+ quest.things[this.size - 6] = this.makeSpikyDoor();
+ for(var i = 0; i < 7; i++){
+ if(i != 3 && i != 5) this.buffers[i][this.size - 6] = this.makeSpikyDoor();
+ }
+ this.buffers[5][this.size - 6] = this.makeDoor();
+
+ // We add teleporting gates
+ quest.things[this.size - 3] = this.makeTeleportingGate();
+ quest.things[this.size - 5] = this.makeTeleportingGate();
+ for(var i = 0; i < 7; i++){
+ if(i != 3){
+ this.buffers[i][this.size - 3] = this.makeTeleportingGate();
+ this.buffers[i][this.size - 5] = this.makeTeleportingGate();
+ }
+ }
+
+ // We set the steps
+ this.addRockStep = 0;
+ this.step = 0;
+
+ // We set the time spent
+ this.timeSpent = 0;
+ },
+
+ teleportCharacter : function(gatesIndex){
+ var index = quest.getCharacterIndex();
+
+ quest.things[0] = quest.things[index];
+ quest.things[index] = quest.makeNoneThing();
+
+ quest.things[gatesIndex] = quest.makeNoneThing();
+ for(var i = 0; i < 7; i++){
+ if(i != this.bufferPosition){
+ this.buffers[i][gatesIndex] = quest.makeNoneThing();
+ }
+ }
+ },
+
+ checkStep1 : function(){
+ var index = quest.getCharacterIndex();
+
+ if(index >= this.size - 7) this.step = 1;
+ },
+
+ checkStep2 : function(){
+ for(var i = 0; i < 7; i++){
+ if((i != this.bufferPosition && this.buffers[i][this.size-5].text != " * ") || (i == this.bufferPosition && quest.things[this.size-5].text != " * ")){
+ this.teleportCharacter(this.size-5);
+ this.step = 2;
+ break;
+ }
+ }
+ },
+
+ checkStep3 : function(){
+ var index = quest.getCharacterIndex();
+
+ if(index >= this.size - 5) this.step = 3;
+ },
+
+ checkStep4 : function(){
+ for(var i = 0; i < 7; i++){
+ if((i != this.bufferPosition && this.buffers[i][this.size-3].text != " * ") || (i == this.bufferPosition && quest.things[this.size-3].text != " * ")){
+ this.teleportCharacter(this.size-3);
+ this.step = 4;
+ this.timeSpent = 0;
+ break;
+ }
+ }
+ },
+
+ goDown : function(){
+ var pos = this.bufferPosition;
+
+ // If we're questing the hell
+ if(quest.weAreQuestingRightNow && land.getLandIndexFromName("Hell") == quest.currentLandIndex){
+ // If we're not already at the buffer 2
+ if(this.bufferPosition != 6){
+ // If we were able to swap, change the buffer position
+ if(this.swapBufferAndQuestThings(pos, pos + 1)){
+ this.bufferPosition += 1;
+ this.checkDevil();
+ quest.updateOnPage();
+ }
+ }
+ }
+ },
+
+ goUp : function(){
+ var pos = this.bufferPosition;
+
+ // If we're questing the hell
+ if(quest.weAreQuestingRightNow && land.getLandIndexFromName("Hell") == quest.currentLandIndex){
+ // If we're not already at the buffer 0
+ if(this.bufferPosition != 0){
+ // If we were able to swap, change the buffer position
+ if(this.swapBufferAndQuestThings(pos, pos - 1)){
+ this.bufferPosition -= 1;
+ this.checkDevil();
+ quest.updateOnPage();
+ }
+ }
+ }
+ },
+
+ swapBufferAndQuestThings : function(now, after){
+ var index = quest.getCharacterIndex();
+ var character = quest.things[index];
+
+ // If we will be able to move on the "after" buffer, we swap (if we have some hp, too)
+ if(this.buffers[after][index].type == "none" && character.hp > 0){
+ // We save the quest things in the old buffer
+ this.buffers[now] = quest.things.slice(0);
+ // We delete the character from the old buffer
+ this.buffers[now][index] = quest.makeNoneThing();
+ // We put the new buffer into the quest things
+ quest.things = this.buffers[after].slice(0);
+ // We add the character
+ quest.things[index] = character;
+ // We return true
+ return true;
+ }
+
+ // Else we return false
+ return false;
+ },
+
+ checkDevil : function(){
+ // If the devil isn't on the line of the character
+ if(quest.things[this.size-1].text != "DEV"){
+ // We move it
+ for(var i = 0; i < 7; i++){
+ if(i != this.bufferPosition && this.buffers[i][this.size-1].text == "DEV"){
+ quest.things[this.size-1] = this.buffers[i][this.size-1];
+ this.buffers[i][this.size-1] = quest.makeNoneThing();
+ break;
+ }
+ }
+ }
+ },
+
+ makeDevil : function(){
+ return land.createMob("DEV", 250, 250, "religion", "It's the devil itself!", [drops.createDrop("candies", 100000)]);
+ },
+
+ makeTeleportingGate : function(){
+ return land.createMob(" * ", 120, 120, "none", "A teleporting gate, made by the devil itself.", []);
+ },
+
+ makeMiddleCreature : function(){
+ switch(this.step){
+ case 0:
+ if(random.oneChanceOutOf(3)){
+ return this.makeDemon();
+ }
+ break;
+ case 2:
+ if(random.oneChanceOutOf(4)){
+ return this.makeBanshee();
+ }
+ break;
+ case 3:
+ if(random.oneChanceOutOf(3)){
+ return castleKeep.makeFireball();
+ }
+ break;
+ case 4:
+ if(this.timeSpent < 50 && this.timeSpent % 2 == 0){
+ return castleStairs.makeGhost();
+ }
+ else if(this.timeSpent < 70){
+ // nothing
+ }
+ else if(this.timeSpent < 90){
+ if(random.oneChanceOutOf(5)){
+ return castleKeep.makeFireball();
+ }
+ }
+ else if(this.timeSpent < 110){
+ if(random.oneChanceOutOf(4)){
+ return castleKeep.makeFireball();
+ }
+ }
+ else if(this.timeSpent < 130){
+ if(random.oneChanceOutOf(3)){
+ return castleKeep.makeFireball();
+ }
+ }
+ else if(this.timeSpent < 170){
+ if(random.oneChanceOutOf(2)){
+ return castleKeep.makeFireball();
+ }
+ }
+ else{
+ return castleKeep.makeFireball();
+ }
+ break;
+ }
+
+ return quest.makeNoneThing();
+ },
+
+ makeSideCreature : function(){
+ switch(this.step){
+ case 0:
+ return this.makeMiddleCreature();
+ break;
+ case 2:
+ if(random.oneChanceOutOf(5)){
+ return castleStairs.makeGhost();
+ }
+ break;
+ case 3:
+ if(random.oneChanceOutOf(4)){} // nothing
+ else{
+ return castleStairs.makeGhost();
+ }
+ break;
+ case 4:
+ return this.makeMiddleCreature();
+ break;
+ }
+
+ return quest.makeNoneThing();
+ },
+
+ makeDemon : function(){
+ return land.createMob("DEM", 90, 90, "demon claws", "A demon.", []);
+ },
+
+ makeBanshee : function(){
+ return land.createMob("BSH", 160, 160, "?", "A banshee, omen of death.", []);
+ },
+
+ makeDoor : function(){
+ return land.createMob("|-|", 300, 300, "none", "A strong door. Hard to break.", []);
+ },
+
+ makeSpikyDoor : function(){
+ return land.createMob("|-|", 300, 300, "spikes", "A strong door. Hard to break. There are spikes on it, it hurts!", []);
+ },
+
+ getText : function(){
+ // Create the text var
+ var text = "";
+
+ // Add the i & k instructions
+ text += "Press i to go up and k to go down. (if it doesn't work, click on the page to gain focus)";
+
+ text += "\n";
+
+ // Open the span
+ text += "";
+
+ text += "\n";
+
+ // We add buffers
+ for(var i = 0; i < 7; i++){
+ if(i != this.bufferPosition){
+ for(var j = 0; j < this.size; j++){
+ if(this.buffers[i][j].type != "none"){
+ text += this.buffers[i][j].text;
+ }
+ else text += " ";
+ }
+ }
+ else{
+ for(var j = 0; j < this.size; j++){
+ if(quest.things[j].type != "none"){
+ text += quest.things[j].text;
+ }
+ else text += " ";
+ }
+ }
+
+ text += "\n";
+ }
+
+ // We make the lava lake
+ for(var i = 0; i < Math.floor(this.size/2); i++){
+ switch(this.lavaLakeStep){
+ case 0: case 1: text += "_.-'-."; break;
+ case 2: case 3: text += "._.-'-"; break;
+ case 4: case 5: text += "-._.-'"; break;
+ case 6: case 7: text += "'-._.-"; break;
+ case 8: case 9: text += "-'-._."; break;
+ case 10: case 11: text += ".-'-._"; break;
+ }
+ }
+
+ // Close the span
+ text += ""
+
+ return text;
+ }
+
+};
diff --git a/static/candies/scripts/htmlInteraction.js b/static/candies/scripts/htmlInteraction.js
new file mode 100755
index 00000000..82a50be3
--- /dev/null
+++ b/static/candies/scripts/htmlInteraction.js
@@ -0,0 +1,76 @@
+var htmlInteraction = {
+
+ setElementDisplay : function(id, display){
+ document.getElementById(id).style.display = display;
+ },
+
+ getElement : function(id){
+ return document.getElementById(id);
+ },
+
+ setElementVisibility : function(id, bool){
+ if(bool) document.getElementById(id).style.visibility = "visible";
+ else document.getElementById(id).style.visibility = "hidden";
+ },
+
+ isElementVisible : function(id){
+ if(document.getElementById(id).style.visibility == "hidden") return false;
+ return true;
+ },
+
+ setInnerHtml : function(id, value){
+ document.getElementById(id).innerHTML = value;
+ },
+
+ disableButton : function(id){
+ this.getElement(id).disabled = "disabled";
+ },
+
+ disableButtonClass : function(id){
+ var arr = document.getElementsByClassName(id);
+ for(var i = 0; i < arr.length; i++){
+ arr[i].disabled = "disabled";
+ }
+ },
+
+ enableButton : function(id){
+ this.getElement(id).disabled = "";
+ },
+
+ enableButtonClass : function(id){
+ var arr = document.getElementsByClassName(id);
+ for(var i = 0; i < arr.length; i++){
+ arr[i].disabled = "";
+ }
+ },
+
+ showButton : function(id){
+ htmlInteraction.setElementVisibility(id, true);
+ },
+
+ showButtonClass : function(id){
+ var arr = document.getElementsByClassName(id);
+ for(var i = 0; i < arr.length; i++){
+ arr[i].style.visibility = "visible";
+ }
+ },
+
+ hideButton : function(id){
+ htmlInteraction.setElementVisibility(id, false);
+ },
+
+ hideButtonClass : function(id){
+ var arr = document.getElementsByClassName(id);
+ for(var i = 0; i < arr.length; i++){
+ arr[i].style.visibility = "hidden";
+ }
+ },
+
+ setButtonOnclick : function(id, value){
+ this.getElement(id).onclick = value;
+ },
+
+ focusElement : function(id){
+ this.getElement(id).focus();
+ }
+};
diff --git a/static/candies/scripts/hut.js b/static/candies/scripts/hut.js
new file mode 100755
index 00000000..6f6ff7da
--- /dev/null
+++ b/static/candies/scripts/hut.js
@@ -0,0 +1,155 @@
+var hut = {
+
+ // Variables
+ shown : false,
+ speech : "",
+ step : 0,
+
+ // Functions
+ throwLollipops : function(){
+ if(lollipops.nbrOwned >= 10){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 10);
+ this.setStep(1);
+ this.setSpeech("I see that you have lollipops... I could cast spells for you, in exchange of some sweets... I looove lollipops!");
+ this.updateOnPage();
+ }
+ },
+
+ acceptProposition : function(){
+ this.setStep(2);
+ this.setSpeech("See for yourself. My prices are high, but the spells are great!");
+ this.updateOnPage();
+ },
+
+ setStep : function(value){
+ this.step = value;
+ },
+
+ setSpeech : function(value){
+ this.speech = value;
+ },
+
+ updateOnPage : function(){
+ var text = "";
+
+ // Hut drawing
+ switch(this.step){
+ case 0:
+ text += "\
+/\\)\\))/\\(/|)\\))/((||\\/)\\)\\\n\
+(/((\\///)))/(\\\\(/)\\\\\\\\\\)\\)\n\
+.__/(|_/| |\\_|)/__.\n\
+ | |_/| |\\_| |\n\
+ | |_/| |\\_| |\n\
+.__| |_/| |\\_| |__.\n\
+ |_/| |\\_|\n\
+ |_/| |\\_|\n\
+._ |_/|________|\\_| _.\n\
+ '-.|_/ \\_|.-'\
+"
+
+ text += "\n\n";
+ break;
+ default:
+ text += "\
+/\\)\\))/\\(/|)\\))/((||\\/)\\)\\\n\
+(/((\\///)))/(\\\\(/)\\\\\\\\\\)\\)\n\
+.__/(|_/| _|\\_ |\\_|)/__.\n\
+ | |_/| (\"} |\\_| |\n\
+ | |_/|i_.-@-._|\\_| |\n\
+.__| |_/|8--, .-|\\_| |__.\n\
+ |_/|I /==\\ |\\_|\n\
+ |_/|I | \\|\\_|\n\
+._ |_/|I__/___\\|\\_| _.\n\
+ '-.|_/ \\_|.-'\n\n\
+"
+ break;
+ }
+
+ // Speech & spells drawing
+ switch(this.step){
+ case 1:
+ text += speech.makeSpeechFromText(this.speech, 24, "");
+ text += "\n\n";
+ break;
+ case 2:
+ text += speech.makeSpeechFromText(this.speech, 24, "");
+ text += this.getSpellsButtons();
+ break;
+ }
+
+ text += "\n\n";
+
+ htmlInteraction.setInnerHtml("map", text);
+
+ if(this.step == 0) buttons.checkHut();
+ if(this.step == 2) buttons.checkHut();
+ },
+
+ getSpellsButtons : function(){
+ var text = "\n";
+
+ for(var i = 0; i < spells.list.length; i++){
+ text += "\n";
+ }
+
+ // We maybe add the surpass yourself button
+ if(quest.maxLandOrder == 7 && yourself.canSurpass == false){
+ text += "\n";
+ text += "\n";
+ }
+
+ return text;
+ },
+
+ surpass : function(){
+ if(lollipops.nbrOwned >= 1000000){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 1000000);
+ this.setSpeech("You are now able to surpass yourself. Congratulations!");
+ yourself.setCanSurpass(true);
+ this.updateOnPage();
+ }
+ },
+
+ canThisSpellBeUsed : function(id){
+ // Check the conditions, return false if some of the conditions are not met
+ for(var i = 0; i < spells.list[id].conditions.length; i++){
+ switch(spells.list[id].conditions[i]){
+ case "specialSword":
+ if(sword.specialSword == false) return false;
+ break;
+ }
+ }
+
+ // Check the price, return false if the price isn't met
+ if(spells.list[id].price() > lollipops.nbrOwned) return false;
+
+ return true;
+ },
+
+ enter : function(){
+ objects.leave();
+
+ this.shown = true;
+
+ this.updateOnPage();
+ },
+
+ leave : function(){
+ this.shown = false;
+
+ htmlInteraction.setInnerHtml("map", "");
+ //buttons.enableHomeButtons();
+ },
+
+ useSpell : function(id){
+ if(lollipops.nbrOwned >= spells.list[id].price()){
+ lollipops.setNbrOwned(lollipops.nbrOwned - spells.list[id].price());
+ this.setSpeech(spells.list[id].speech);
+ spells.list[id].effect();
+ this.updateOnPage();
+ inventory.updateOnPage();
+ }
+ }
+
+};
diff --git a/static/candies/scripts/inventory.js b/static/candies/scripts/inventory.js
new file mode 100755
index 00000000..b0fef79a
--- /dev/null
+++ b/static/candies/scripts/inventory.js
@@ -0,0 +1,161 @@
+var inventory = {
+
+ // Variables
+ magicianHatLetter : "",
+
+ // Functions
+ setMagicianHatLetter : function(value){
+ this.magicianHatLetter = value;
+ },
+
+ updateOnPage : function(){
+ // Check for the magician hat letter : if we have the magician hat but no letter is set yet
+ if(objects.list.magicianHat.have && this.magicianHatLetter == ""){
+ this.setMagicianHatLetter(" " + random.getRandomLetter());
+ }
+
+ // Sword
+ switch(sword.name){
+ case "wooden sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiWoodenSwordWithoutButton); break;
+ case "copper sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiCopperSwordWithoutButton); break;
+ case "iron sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiIronSwordWithoutButton); break;
+ case "silver sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiSilverSwordWithoutButton); break;
+ case "diamond sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiDiamondSwordWithoutButton); break;
+ case "candy diamond sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiCandyDiamondSword); break;
+ case "polished candy diamond sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiPolishedCandyDiamondSword); break;
+ case "chocolate sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiChocolateSword); break;
+ case "sharp chocolate sword": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiSharpChocolateSword); break;
+ case "Sword of Flames": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiSwordOfFlames + "\n\nLevel : " + sword.specialPower); break;
+ case "Sword of Life": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiSwordOfLife + "\n\nLevel : " + sword.specialPower); break;
+ case "Sword of Summoning": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiSwordOfSummoning + "\n\nLevel : " + sword.specialPower); break;
+ case "Sword of Liflamesummoning": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiSwordOfLiflamesummoning + "\n\nLevel : " + sword.specialPower); break;
+ case "Sword of Randomness": htmlInteraction.setInnerHtml("sword_without_button", sword.asciiSwordOfRandomness + "\n\nLevel : infinite + " + sword.specialPower); break;
+ }
+
+ // Objects
+ this.updateObjectOnPage("inventory_key", objects.list.key, this.asciiKey, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_boots", objects.list.boots, this.asciiBoots, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_magician_hat", objects.list.magicianHat, this.magicianHatLetter + "\n" + this.asciiMagicianHat, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_pink_ring", objects.list.pinkRing, this.asciiPinkRing, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_candies_converter", objects.list.candiesConverter, this.asciiCandiesConverter, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_plate_armour", objects.list.plateArmour, this.asciiPlateArmour, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_cauldron", objects.list.cauldron, this.asciiCauldron, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_magical_horn", objects.list.magicalHorn, this.asciiMagicalHorn, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_horn_of_plenty", objects.list.hornOfPlenty, this.asciiHornOfPlenty, this.asciiNoObject);
+ this.updateObjectOnPage("inventory_old_amulet", objects.list.oldAmulet, this.asciiOldAmulet, this.asciiNoObject);
+
+ if(developperComputer.won){
+ htmlInteraction.setInnerHtml("inventory_won1", "
").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n){return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window);
\ No newline at end of file
diff --git a/static/candies/scripts/land.js b/static/candies/scripts/land.js
new file mode 100755
index 00000000..918bb8ee
--- /dev/null
+++ b/static/candies/scripts/land.js
@@ -0,0 +1,82 @@
+var land = {
+
+ // Variables
+ list : [],
+ ponyTime : false,
+
+ // Functions
+ createMob : function(text, max_hp, hp, weapon, description, drops){
+ if(this.ponyTime == false)
+ return {type:"mob", text:text, max_hp:max_hp, hp:hp, weapon:weapon, description:description, drops:drops};
+ else return {type:"mob", text:"PON", max_hp:max_hp, hp:hp, weapon:weapon, description:"A pony", drops:drops};
+ },
+
+ createFakeCharacter : function(){
+ if(this.ponyTime == false)
+ return {type:"fake", text:"\\o/", max_hp:0, hp:0, weapon:"none", description:"", drops:[]};
+ else return {type:"fake", text:"PON", max_hp:0, hp:0, weapon:"none", description:"A pony", drops:[]};
+ },
+
+ createAlly : function(text, max_hp, hp, weapon, description, drops){
+ if(this.ponyTime == false)
+ return {type:"ally", text:text, max_hp:max_hp, hp:hp, weapon:weapon, description:description, drops:drops};
+ else return {type:"ally", text:"PON", max_hp:max_hp, hp:hp, weapon:weapon, description:"A pony", drops:drops};
+ },
+
+ createTrap : function(text, max_hp, hp, weapon, description, drops){
+ if(this.ponyTime == false)
+ return {type:"trap", text:text, max_hp:max_hp, hp:hp, weapon:weapon, description:description, drops:drops};
+ else return {type:"trap", text:"PON", max_hp:max_hp, hp:hp, weapon:weapon, description:"A pony", drops:drops};
+ },
+
+ addLand : function(name, size, order, loadFunction, getTextFunction, moveFunction){
+ this.list.push({name:name, size:size, order:order, unlocked:false, loadFunction:loadFunction, getTextFunction:getTextFunction, moveFunction:moveFunction});
+ },
+
+ getLandIndexFromOrder : function(order){
+ for(var i = 0; i < this.list.length; i++){
+ if(this.list[i].order == order){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getLandIndexFromName : function(name){
+ for(var i = 0; i < this.list.length; i++){
+ if(this.list[i].name == name){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ updateListOnPage : function(maxOrder){
+ var index, list, option;
+
+ // We iterate over all order from 0 to maxOrder
+ for(var i = 0; i <= maxOrder; i++){
+ index = this.getLandIndexFromOrder(i); // We get the index of the land with the order i
+ // If the land of index "index" isn't already unlocked and is correct (!= -1)
+ if(index != -1 && this.list[index].unlocked == false){
+ list = htmlInteraction.getElement("quest_destination"); // We get the list
+ option = document.createElement("option"); // We create the new element to add to the list
+ option.text = this.list[index].name; // We set its text
+ // We add it to the list
+ try{ list.add(option, list.options[null]); }
+ catch(e){ list.add(option, null); }
+ // We set that it is unlocked now
+ this.list[index].unlocked = true;
+ }
+ }
+ },
+
+ getText : function(){
+ return this.list[quest.currentLandIndex].getTextFunction();
+ },
+
+ load : function(){
+ return this.list[quest.currentLandIndex].loadFunction();
+ }
+
+};
diff --git a/static/candies/scripts/loadPrompt.js b/static/candies/scripts/loadPrompt.js
new file mode 100755
index 00000000..b02bd720
--- /dev/null
+++ b/static/candies/scripts/loadPrompt.js
@@ -0,0 +1,7 @@
+function loadPrompt() {
+ var code = prompt("Please enter your five-character code.", "");
+
+ if(code != null) {
+ window.location = 'index.php?pass=' + code;
+ }
+}
\ No newline at end of file
diff --git a/static/candies/scripts/lollipops.js b/static/candies/scripts/lollipops.js
new file mode 100755
index 00000000..fa638c23
--- /dev/null
+++ b/static/candies/scripts/lollipops.js
@@ -0,0 +1,105 @@
+var lollipops = {
+
+ // Variables
+ nbrOwned : 0,
+ nbrBought : 0,
+ nbrInStock : 1000,
+ stockShortage : false,
+
+ // Functions
+ buy1 : function(){
+ if(candies.nbrOwned >= shop.oneLollipopPrice && this.nbrInStock >= 1){
+ candies.setNbrOwned(candies.nbrOwned - shop.oneLollipopPrice);
+ this.setNbrOwned(this.nbrOwned + 1);
+ this.setNbrBought(this.nbrBought + 1);
+ this.setNbrInStock(this.nbrInStock - 1);
+ shop.setMerchantSpeech("Thanks for buyin'! Here's your " + this.getFlavour() + " shout out.");
+ }
+ },
+
+ buy10 : function(){
+ if(candies.nbrOwned >= shop.tenLollipopsPrice && this.nbrInStock >= 10){
+ candies.setNbrOwned(candies.nbrOwned - shop.tenLollipopsPrice);
+ this.setNbrOwned(this.nbrOwned + 10);
+ this.setNbrBought(this.nbrBought + 10);
+ this.setNbrInStock(this.nbrInStock - 10);
+ shop.setMerchantSpeech("Thanks for buyin'! Here's your ten shout outs. Various kinds.");
+ }
+ else shop.setMerchantSpeech("I'm sorry, we don't have enough shout outs in stock to sell you ten of them. We currently have " + this.nbrInStock + " shout outs in stock.");
+ },
+
+ getFlavour : function(){
+ var fruits = ["classic", "robot", "Kool-Aid Man", "programming", "race car", "roller coaster", "the golf clap one" ];
+ var uncommon = ["chocolate", "cookie", "pancake", "water", "tomato", "kitten"];
+ var unrealistic = ["leprechaun", "lollipop", "snow", "storm", "door", "dracula"];
+ var abstract = ["gluttony", "friendship", "puzzle", "fine art", "cuteness"];
+
+ var chances = [];
+ if(this.nbrBought < 10) chances = [1];
+ else if(this.nbrBought < 10) chances = [1];
+ else if(this.nbrBought < 15) chances = [0.9, 1];
+ else if(this.nbrBought < 20) chances = [0.8, 1];
+ else if(this.nbrBought < 25) chances = [0.7, 1];
+ else if(this.nbrBought < 30) chances = [0.5, 1];
+ else if(this.nbrBought < 35) chances = [0.4, 0.9, 1];
+ else if(this.nbrBought < 40) chances = [0.3, 0.8, 1];
+ else if(this.nbrBought < 45){
+ if(this.nbrBought == 42 && random.flipACoin()) return "space";
+ else chances = [0.2, 0.7, 1];
+ }
+ else if(this.nbrBought < 50) chances = [0.1, 0.6, 1];
+ else if(this.nbrBought < 55) chances = [0.1, 0.5, 1];
+ else if(this.nbrBought < 60) chances = [0.1, 0.4, 0.9];
+ else if(this.nbrBought < 65) chances = [0.1, 0.3, 0.8];
+ else if(this.nbrBought < 70) chances = [0.1, 0.2, 0.7];
+ else if(this.nbrBought < 75) chances = [0.1, 0.2, 0.6];
+ else if(this.nbrBought < 80) chances = [0.1, 0.2, 0.5];
+ else if(this.nbrBought < 85) chances = [0.1, 0.2, 0.4];
+ else if(this.nbrBought == 1337 && random.flipACoin()) return "leet";
+ else chances = [0.1, 0.2, 0.3];
+
+ var r = random.getRandomFloat()
+ if(r < chances[0]) return random.pickRandomly(fruits);
+ else if(r < chances[1]) return random.pickRandomly(uncommon);
+ else if(r < chances[2]) return random.pickRandomly(unrealistic);
+ else return random.pickRandomly(abstract);
+ },
+
+ delivery : function(){
+ this.setNbrInStock(this.nbrInStock + 15 + random.getRandomIntUpTo(10));
+ window.setTimeout(this.delivery.bind(this), 900000); // One delivery every 15 minutes
+ },
+
+ setNbrOwned : function(value){
+ this.nbrOwned = value;
+ if(this.nbrOwned != 1) htmlInteraction.setInnerHtml("shout outs", "You have " + numberWithCommas(this.nbrOwned) + " shout outs!");
+ else htmlInteraction.setInnerHtml("shout outs", "You have 1 shout out!");
+ htmlInteraction.setElementVisibility("shout outs", true);
+ buttons.checkLollipops();
+ cauldron.updateActionsInfoOnPage();
+ computer.updateLollipops();
+ },
+
+ setNbrBought : function(value){
+ this.nbrBought = value;
+ },
+
+ setNbrInStock : function(value){
+ // Set the value
+ this.nbrInStock = value;
+
+ // If > 100, decrease it
+ if(this.nbrInStock > 140) this.nbrInStock = 140;
+
+ // Handle lollipops stock shortage
+ if(this.stockShortage == false && this.nbrInStock == 0){
+ this.stockShortage = true;
+ buttons.checkLollipopsStockShortage();
+ }
+ else if(this.stockShortage == true && this.nbrInStock != 0){
+ this.stockShortage = false;
+ buttons.checkLollipopsStockShortage();
+ }
+ }
+
+};
diff --git a/static/candies/scripts/main.js b/static/candies/scripts/main.js
new file mode 100755
index 00000000..b105d885
--- /dev/null
+++ b/static/candies/scripts/main.js
@@ -0,0 +1,135 @@
+
+var main = {
+
+ // Variables
+ nbrOfSecondsSinceLastMinInterval : 0,
+ nbrOfSecondsSinceLastHourInterval : 0,
+ nbrOfSecondsSinceLastDayInterval : 0,
+ saveShown : false,
+
+ // Functions
+ onload : function(){
+ // Prevents some stupid refresh bugs of the browser
+ htmlInteraction.enableButtonClass("home_button");
+
+ // Various loads
+ peacefulForest.onload();
+ mountGoblin.onload();
+ underwaterCave.onload();
+ castleEntrance.onload();
+ castleStairs.onload();
+ castleKeep.onload();
+ cowLevel.onload();
+ sea.onload();
+ desert.onload();
+ hell.onload();
+ yourself.onload();
+ chuckNorris.onload();
+ developperGarden.onload();
+ developperMoat.onload();
+ developperComputer.onload();
+ shop.onload();
+ candies.onload();
+ spells.onload();
+ potions.onload();
+ sword.onload();
+ cauldron.onload();
+ tabs.onload();
+
+ // Loading after various loads
+ quest.onloadAfter(); // This must be call after other loads because it needs the different quests to be loaded
+
+ // Loading a save
+
+ // First actions
+ window.setInterval(this.oneTenthSecInterval.bind(this), 100);
+ window.setInterval(this.secInterval.bind(this), 1000);
+ },
+
+ oneTenthSecInterval : function(){
+ // We try to convert candies into lollipops
+ candiesConverter.convert();
+ },
+
+ secInterval : function(){
+ // Candies
+ if(objects.list.oldAmulet.have == false) candies.setNbrOwned(candies.nbrOwned + candies.candiesPerSecond);
+ else candies.setNbrOwned(candies.nbrOwned + candies.candiesPerSecond*3);
+
+ // Quest tired time
+ if(objects.list.pinkRing.have == false) quest.setTiredTime(quest.tiredTime - 1);
+ else quest.setTiredTime(quest.tiredTime - 2);
+
+ // Lollipop farm
+ if(farm.productionDelayType == "sec"){
+ if(objects.list.hornOfPlenty.have == false) lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction);
+ else lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction*3);
+ }
+
+ // Cauldron
+ cauldron.moveSmoke();
+ cauldron.increaseActionTimer();
+
+ // We increase nbrOfSeconds variables
+ this.nbrOfSecondsSinceLastMinInterval += 1;
+ this.nbrOfSecondsSinceLastHourInterval += 1;
+ this.nbrOfSecondsSinceLastDayInterval += 1;
+
+ // We possibly trigger minInterval
+ if(this.nbrOfSecondsSinceLastMinInterval >= 60){
+ this.nbrOfSecondsSinceLastMinInterval = 0;
+ this.minInterval();
+ }
+
+ // We possibly trigger hourInterval
+ if(this.nbrOfSecondsSinceLastHourInterval >= 3600){
+ this.nbrOfSecondsSinceLastHourInterval = 0;
+ this.hourInterval();
+ }
+
+ // We possibily trigger dayInterval
+ if(this.nbrOfSecondsSinceLastDayInterval >= 86400){
+ this.nbrOfSecondsSinceLastDayInterval = 0;
+ this.dayInterval();
+ }
+ },
+
+ minInterval : function(){
+ // Lollipop farm
+ if(farm.productionDelayType == "min"){
+ if(objects.list.hornOfPlenty.have == false) lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction);
+ else lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction*3);
+ }
+ },
+
+ hourInterval : function(){
+ // Lollipop farm
+ if(farm.productionDelayType == "hour"){
+ if(objects.list.hornOfPlenty.have == false) lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction);
+ else lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction*3);
+ }
+ },
+
+ dayInterval : function(){
+ // Lollipop farm
+ if(farm.productionDelayType == "day"){
+ if(objects.list.hornOfPlenty.have == false) lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction);
+ else lollipops.setNbrOwned(lollipops.nbrOwned + farm.lollipopsProduction*3);
+ }
+ },
+
+ setNbrOfSecondsSinceLastMinInterval : function(value){
+ this.nbrOfSecondsSinceLastMinInterval = value;
+ },
+
+ setNbrOfSecondsSinceLastHourInterval : function(value){
+ this.nbrOfSecondsSinceLastHourInterval = value;
+ },
+
+ setNbrOfSecondsSinceLastDayInterval : function(value){
+ this.nbrOfSecondsSinceLastDayInterval = value;
+ }
+};
+
+window.onload = main.onload.bind(main);
+
diff --git a/static/candies/scripts/mountGoblin.js b/static/candies/scripts/mountGoblin.js
new file mode 100755
index 00000000..685fd8d3
--- /dev/null
+++ b/static/candies/scripts/mountGoblin.js
@@ -0,0 +1,49 @@
+var mountGoblin = {
+
+ // Variables
+ basicChestProbability : 50,
+
+ // Functions
+ onload : function(){
+ land.addLand("Mount Goblin", 28, 1, this.load.bind(this), this.getText.bind(this));
+ },
+
+ setBasicChestProbability : function(value){
+ this.basicChestProbability = value;
+ },
+
+ load : function(){
+ for(var i = 1; i < quest.things.length; i++){
+ if(random.flipACoin()){
+ // If we're not at the top of the mount
+ if(i < 12 || i > 15){
+ // 1 chance out of x we spawn a CHS (chest !!)
+ if(random.oneChanceOutOf(this.basicChestProbability)){
+ this.setBasicChestProbability(this.basicChestProbability + 50);
+ quest.things[i] = quest.makeBasicChest();
+ }
+ // 1 chance out of 7 we spaw a GSB
+ else if(random.oneChanceOutOf(7)) quest.things[i] = land.createMob("GSB", 20, 5 + random.getRandomIntUpTo(5), "claws", "A sick goblin. It smells.", [drops.createDrop("candies", 3 + random.getRandomIntUpTo(3))]);
+ // Else we spawn a GOB
+ else quest.things[i] = land.createMob("GOB", 20, 20, "claws", "A nasty goblin.", [drops.createDrop("candies", 3 + random.getRandomIntUpTo(3))]);
+ }
+ else{
+ quest.things[i] = land.createMob("GTB", 30, 30, "dagger", "A tenacious goblin. Oh, he has a dagger, too.", [drops.createDrop("candies", 9 + random.getRandomIntUpTo(9)), drops.createDrop("object", "key", random.oneChanceOutOf(2)), drops.createDrop("object", "boots", random.oneChanceOutOf(5)), drops.createDrop("object", "swampMap", random.oneChanceOutOf(5)), drops.createDrop("object", "hutMap", random.oneChanceOutOf(5))]);
+ }
+ }
+ }
+ },
+
+ getText : function(){
+ var text = "";
+
+ text += " "; for(var i = 12; i < 16; i++) text += quest.things[i].text; text += "\n";
+ text += " "; for(var i = 9; i < 12; i++) text += quest.things[i].text; text += "/ \\/ \\/ \\/ \\"; for(var i = 16; i < 19; i++) text += quest.things[i].text; text += "\n";
+ text += " "; for(var i = 6; i < 9; i++) text += quest.things[i].text; text += "/ \\/ \\/ \\ / \\ \\ / \\/ \\/ \\"; for(var i = 19; i < 22; i++) text += quest.things[i].text; text += "\n";
+ text += " "; for(var i = 3; i < 6; i++) text += quest.things[i].text; text += "/ \\/ \\/ \\ \\ / \\/ \\ \\/ / \\ / \\/ \\/ \\"; for(var i = 22; i < 25; i++) text += quest.things[i].text; text += "\n";
+ text += ""; for(var i = 0; i < 3; i++) text += quest.things[i].text; text += "/ \\/ \\/ \\ / / \\ / / \\ / / \\/ / \\ / \\/ \\/ \\"; for(var i = 25; i < 28; i++) text += quest.things[i].text;
+
+ return text;
+ }
+
+};
diff --git a/static/candies/scripts/objects.js b/static/candies/scripts/objects.js
new file mode 100755
index 00000000..1ffa3f5f
--- /dev/null
+++ b/static/candies/scripts/objects.js
@@ -0,0 +1,40 @@
+var objects = {
+
+ // Variables
+ list : {
+ key : {have:false, found:false, text:"a key", name:"The lollipop farm's key.", description:"This key brings a lollipop farm to your candy box."},
+ boots : {have:false, found:false, text:"a pair of boots", name:"The seven-league boots.", description:"These boots increase your speed during quests."},
+ swampMap : {have:false, found:false, text:"a map", name:"The map to the Swampy Swamp.", description:"The Swampy Swamp is the swampiest swamp you've ever seen."},
+ hutMap : {have:false, found:false, text:"a map", name:"The map to the sorceress' hut.", description:"In this hut lives a powerful witch! She might help you... but not for free."},
+ wellMap : {have:false, found:false, text:"a map", name:"The map to the wishing well.", description:"Make a wish, make it so, you may shine, you may glow..."},
+ magicianHat : {have:false, found:false, text:"a hat", name:"The magician's hat.", description:"Wearing this hat enhances your magic."},
+ pinkRing : {have:false, found:false, text:"a ring", name:"The pink ring of calmness.", description:"This pink ring will help you control your breath. You will recover faster after a quest."},
+ forgeMap : {have:false, found:false, text:"a map", name:"The map to the forge.", description:"An anvil can be really useful, if you have the appropriate sword.."},
+ candiesConverter : {have:false, found:false, text:"a strange object", name:"The candies converter.", description:"When activated in your candy box, this surprising object quickly converts all your candies into lollipops. One candy gives one lollipop!"},
+ plateArmour : {have:false, found:false, text:"a strong armour", name:"A plate armour.", description:"This strong armour protects you from your enemies. You will lose less health points."},
+ cauldron : {have:false, found:false, text:"a big container", name:"A cauldron.", description:"This cauldron allows you to brew a large variety of potions, using raw, common materials like candies or lollipops."},
+ magicalHorn : {have:false, found:false, text:"a horn", name:"A magical horn.", description:"This magical horn belonged to a unicorn. Carrying it will make you regain health points continuously during a quest!"},
+ hornOfPlenty : {have:false, found:false, text:"a horn", name:"The horn of plenty.", description:"The horn of plenty, stolen from Ploutos by the cow king, who thought it was a real horn. This mythical object will multiply by three your lollipop farm production."},
+ oldAmulet : {have:false, found:false, text:"an amulet", name:"An old amulet.", description:"This old amulet, found on the corpse of a dead warrior, is known to bring prosperity to its owner. It will multiply by three your candies production."}
+ },
+
+ leave : function(){
+ hut.leave();
+ wishingWell.leave();
+ swamp.leave();
+ forge.leave();
+ },
+
+ // Functions
+ setHaveObject : function(name, value){
+ // We set the new "have" value
+ this.list[name].have = value;
+
+ // We check the buttons related to objects, since they may have changed
+ buttons.checkObjects();
+
+ // We update the inventory
+ inventory.updateOnPage();
+ }
+
+};
diff --git a/static/candies/scripts/peacefulForest.js b/static/candies/scripts/peacefulForest.js
new file mode 100755
index 00000000..a3600d07
--- /dev/null
+++ b/static/candies/scripts/peacefulForest.js
@@ -0,0 +1,85 @@
+var peacefulForest = {
+
+ // Variables
+ basicChestProbability : 100,
+ poniesEncountered : 0,
+
+ // Functions
+ onload : function(){
+ land.addLand("The peaceful forest", 30, 0, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ setBasicChestProbability : function(value){
+ this.basicChestProbability = value;
+ },
+
+ move : function(){
+ // Iterate over all things
+ for(var i = 0; i < quest.things.length; i++){
+ // If it's a wood poney (wood poneeeey \o/)
+ if(quest.things[i].text == "WPY"){
+ // We make it move if possible
+ if(random.flipACoin()){
+ // If we can move it to the right
+ if(quest.things[i+1].type == "none"){
+ // We move it to the right
+ quest.things[i+1] = quest.things[i];
+ quest.things[i] = quest.makeNoneThing();
+ }
+ }
+ else{
+ // If we can move it to the left
+ if(quest.things[i-1].type == "none"){
+ // We move it to the left
+ quest.things[i-1] = quest.things[i];
+ quest.things[i] = quest.makeNoneThing();
+ }
+ }
+ }
+ }
+ },
+
+ load : function(){
+ var addedAPoney = false; // Will be true if we added a pony. Useful to avoid adding two ponies in the same quest
+
+ for(var i = 1; i < quest.things.length; i++){
+ if(random.flipACoin()){
+ // 1 chance out of x we spawn a wood poney !!!! (if we didn't already add one)
+ if(random.oneChanceOutOf(300) && addedAPoney == false){
+ addedAPoney = true;
+ quest.things[i] = this.makeWoodPoney();
+ }
+ // 1 chance out of x we spawn a CHS (chest !!)
+ else if(random.oneChanceOutOf(this.basicChestProbability)){
+ this.setBasicChestProbability(this.basicChestProbability + 50);
+ quest.things[i] = quest.makeBasicChest();
+ }
+ // Else we spawn a tree
+ else quest.things[i] = land.createMob("|||", 5, 5, "none", "A tree. It sometimes drop a candy.", [drops.createDrop("candies", random.getRandomIntUpTo(1)), drops.createDrop("object", "key", random.oneChanceOutOf(2))]);
+ }
+ }
+
+ if(addedAPoney){
+ this.setPoniesEncountered(this.poniesEncountered + 1);
+ }
+ },
+
+ setPoniesEncountered : function(value){
+ this.poniesEncountered = value;
+ },
+
+ getText : function(){
+ var text = "";
+
+ for(var i = 0; i < quest.things.length; i++){
+ text += quest.things[i].text;
+ }
+
+ return text;
+ },
+
+ makeWoodPoney : function(){
+ return land.createMob("WPY", 12, 12, "hooves", "A wood poney ! It's a poney ! It the woods !", [drops.createDrop("candies", 42)]);
+ }
+
+};
diff --git a/static/candies/scripts/poke.js b/static/candies/scripts/poke.js
new file mode 100755
index 00000000..e69de29b
diff --git a/static/candies/scripts/potions.js b/static/candies/scripts/potions.js
new file mode 100755
index 00000000..464a2419
--- /dev/null
+++ b/static/candies/scripts/potions.js
@@ -0,0 +1,493 @@
+var potions = {
+
+ // Variables
+ list : {},
+
+ // Functions
+ getCountdown : function(){
+ if(objects.list.magicianHat.have) return 12;
+ return 20;
+ },
+
+ onload : function(){
+ this.addPotion("health", "Health potion", "#ff0000", "potions.heal(50);", "Use this minor health potion during combats to regain some of your health points !", "potion");
+ this.addPotion("escape", "Escape potion", "#51c90f", "potions.escape();", "The escape potion allow escaping from a quest while avoiding any time penalty. It makes you flee really really fast !", "potion");
+ this.addPotion("berserk", "Berserk potion", "#000000", "potions.berserk();", "The berserk potions transforms you into a.. BERSERKEEEER !", "potion");
+ this.addPotion("fireScroll", "Fire scroll", "#dc3e00", "potions.fireScroll();", "This powerful fire scroll will burn your enemy if you use it during a fight.", "scroll");
+ this.addPotion("acidRainScroll", "Acid rain scroll", "#68980b", "potions.acidRainScroll();", "This acid rain scroll will instantly damage everyone in the whole land (including yourself).", "scroll");
+ this.addPotion("teleportScroll", "Teleport scroll", "#7ca0b5", "potions.teleportScroll();", "This teleport scroll will make you go back to the beginning of a quest. Useful to rest a little bit !", "scroll");
+ this.addPotion("earthquakeScroll", "Earthquake scroll", "#470b0b", "potions.earthquakeScroll();", "This earthquake scroll will inflict a lot of damage to everyone in the whole land.", "scroll");
+ this.addPotion("impInvocationScroll", "Imp invocation scroll", "#ff6600", "potions.impInvocationScroll();", "This imp invocation scroll will, if there's enough place, invoke in front of you an imp which will fight for you.", "scroll");
+ this.addPotion("majorHealth", "Major health potion", "#ff0000", "potions.heal(100);", "This major health potion is twice more efficient than the minor one.", "potion");
+ this.addPotion("invulnerability", "Invulnerability potion", "#ef893b", "potions.invulnerability();", "This invulnerability potion will make you invincible for some time, but it fills your stomach : you won't be able to drink another potion for a long time after using it.", "potion");
+ this.addPotion("turtle", "Turtle potion", "#008a13", "potions.turtle();", "When you drink a turtle potion, you become a turtle. Drawback : you walk slower. Benefit : you're way more resistant to your ennemies' attacks.", "potion");
+ this.addPotion("jelly", "Jelly", "#9500b5", "potions.jelly();", "This skillfully prepared jelly explodes on contact of anything trying to go through it, dealing high damage. Using it will place it behind you.", "special");
+ this.addPotion("seed", "Seed", "#3dab3a", "potions.seed();", "This seed is able to make grow a candy tree. The candy tree is made of candies, and it takes a lot of time to cut it down. Using the seed will grow a tree in front of you, if there's enough place.", "special");
+ this.addPotion("cloning", "Cloning potion", "#6d6d6d", "potions.cloning();", "This cloning potion will, well... clone you. Your clone will have the same health points as you when you drank the potion, but he won't have your armor nor your sword. He will fight using a \"cloned sword\", which deals a correct amount of damage. The clone will be placed in front of you, if there's enough place.", "potion");
+ this.addPotion("superman", "Superman potion", "#ddef17", "potions.superman();", "This superman potion will give you a cape and make you look like superman for the rest of the quest !", "potion");
+ this.addPotion("gmooh", "G.M.O.O.H. potion", "#ff00c0", "potions.gmooh();", "This \"Get Me Out Of Here\" potion will teleport you somewhere else. The destination isn't predictable at all.", "potion");
+ },
+
+ updateOnPage : function(){
+ htmlInteraction.setInnerHtml("quest_potions", this.getText());
+ if(quest.weAreQuestingRightNow) this.updateCountdownOnPage();
+ },
+
+ updateCountdownOnPage : function(){
+ htmlInteraction.setInnerHtml("quest_potions_countdowns", this.getCountdownText());
+ },
+
+ getCountdownText : function(){
+ var text = "";
+
+ // Potions
+ if(quest.berserk) text += "Berserk mode: " + quest.berserkCountdown + "\n";
+ if(quest.turtle) text += "You're a turtle: " + quest.turtleCountdown + "\n";
+ if(quest.invulnerability) text += "Invincible: " + quest.invulnerabilityCountdown + "\n";
+ if(this.list.health.shown || this.list.escape.shown || this.list.berserk.shown || this.list.majorHealth.shown || this.list.invulnerability.shown || this.list.turtle.shown || this.list.cloning.shown || this.list.superman.shown || this.list.gmooh.shown) text += "Potion countdown : " + quest.potionUseCountdown + "\n";
+
+ // Scrolls
+ if(this.list.fireScroll.shown || this.acidRainScroll.shown || this.teleportScroll.shown || this.earthquakeScroll.shown || this.impInvocationScroll.shown) text += "Scroll countdown : " + quest.scrollUseCountdown;
+
+ return text;
+ },
+
+ getText : function(){
+ var text = "";
+
+ // Special stuff
+ text += this.getPotionButtonText(this.list.seed);
+ text += this.getPotionButtonText(this.list.jelly);
+
+ text += "\n";
+
+ // Potions
+ text += this.getPotionButtonText(this.list.health);
+ text += this.getPotionButtonText(this.list.escape);
+ text += this.getPotionButtonText(this.list.berserk);
+
+ text += "\n";
+
+ // Potions bis !
+ text += this.getPotionButtonText(this.list.majorHealth);
+ text += this.getPotionButtonText(this.list.turtle);
+ text += this.getPotionButtonText(this.list.invulnerability);
+ text += this.getPotionButtonText(this.list.superman);
+ text += this.getPotionButtonText(this.list.cloning);
+ text += this.getPotionButtonText(this.list.gmooh);
+
+ text += "\n";
+
+ // Scrolls
+ text += this.getPotionButtonText(this.list.fireScroll);
+ text += this.getPotionButtonText(this.list.acidRainScroll);
+ text += this.getPotionButtonText(this.list.teleportScroll);
+ text += this.getPotionButtonText(this.list.impInvocationScroll);
+ text += this.getPotionButtonText(this.list.earthquakeScroll);
+
+ return text;
+ },
+
+ getPotions : function(potion, nbr){
+ this.setPotionShown(potion, true);
+ potion.nbrOwned += nbr;
+ this.updateOnPage();
+ },
+
+ setPotionShown : function(potion, value){
+ potion.shown = value;
+ },
+
+ setPotionNbrOwned : function(potion, value){
+ potion.nbrOwned = value;
+ },
+
+ buyPotion : function(potion, price){
+ this.getPotions(potion, 1);
+ candies.setNbrOwned(candies.nbrOwned - price);
+ shop.setMerchantSpeech(potion.merchantSpeech);
+ },
+
+ buyScroll : function(price){
+ var maxPower = 2;
+
+ if(objects.list.magicianHat.have) maxPower = 4;
+
+ switch(random.getRandomIntUpTo(maxPower)){
+ case 0:
+ this.buyPotion(this.list.fireScroll, price);
+ break;
+ case 1:
+ this.buyPotion(this.list.acidRainScroll, price);
+ break;
+ case 2:
+ this.buyPotion(this.list.teleportScroll, price);
+ break;
+ case 3:
+ this.buyPotion(this.list.impInvocationScroll, price);
+ break;
+ case 4:
+ this.buyPotion(this.list.earthquakeScroll, price);
+ break;
+ }
+ },
+
+ getPotionButtonText : function(potion){
+ if(potion.shown){
+ var disabled = "";
+ var tooltip = "";
+
+ if(quest.weAreQuestingRightNow == false || potion.nbrOwned <= 0 || ((potion.type == "potion" && quest.potionUseCountdown > 0) || (potion.type == "scroll" && quest.scrollUseCountdown > 0))) disabled = "disabled=disabled";
+ if(quest.weAreQuestingRightNow == false) tooltip = "" + potion.merchantSpeech + "";
+
+ return "\n";
+ }
+ return "";
+ },
+
+ addPotion : function(name, buttonText, buttonColor, action, merchantSpeech, type){
+ this.list[name] = {buttonText:buttonText, buttonColor:buttonColor, action:action, shown:false, nbrOwned:0, merchantSpeech:merchantSpeech, type:type};
+ },
+
+ makeJelly : function(){
+ return land.createTrap("JEL", 1, 1, "powerful explosion", "A jelly !! Go away !", []);
+ },
+
+ makeClone : function(hp, max_hp){
+ return land.createAlly("\\o/", max_hp, hp, "cloned sword", "A clone of you.", []);
+ },
+
+ makeCandyTree : function(){
+ var hp = 0;
+
+ // One chance out of 100 to spawn the Yggdrasil \o/
+ if(random.oneChanceOutOf(100)){
+ return land.createTrap("/Y\\", 10000, 10000, "none", "Yggdrasill is its name, a tall tree, showered with shining loam.", [drops.createDrop("candies", 10000)]);
+ }
+ else{
+ hp = 500 + 100 * random.getRandomIntUpTo(4); // 500 / 600 / 700 / 800 / 900
+ return land.createTrap("\\|/", hp, hp, "none", "A candy tree. I hope you're carrying a good axe.", []);
+ }
+ },
+
+ heal : function(howMuch){
+ // We get the character index
+ var id = quest.getCharacterIndex();
+
+ if(quest.things[id].hp > 0 && ((howMuch == 50 && this.list.health.nbrOwned > 0) || (howMuch == 100 && this.list.majorHealth.nbrOwned > 0))){
+ // We decrement nbrOwned
+ if(howMuch == 50)
+ this.list.health.nbrOwned -= 1;
+ else if(howMuch == 100)
+ this.list.majorHealth.nbrOwned -= 1;
+
+ // We increment hp
+ quest.things[id].hp += howMuch;
+
+ // We set hp = max_hp if hp > max_hp
+ if(quest.things[id].hp > quest.things[id].max_hp){
+ quest.things[id].hp = quest.things[id].max_hp;
+ }
+
+ // We set the countdown
+ quest.potionUseCountdown += this.getCountdown();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ escape : function(){
+ if(this.list.escape.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.escape.nbrOwned -= 1;
+
+ // We tell the quest that we escape
+ quest.escaping = true;
+
+ // We delete all tired time
+ quest.setTiredTime(0);
+ quest.setTiredFound(0);
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ berserk : function(){
+ if(this.list.berserk.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.berserk.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.potionUseCountdown += this.getCountdown();
+
+ // We tell the quest that we are now in berserk mode
+ quest.beginBerserk();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ fireScroll : function(){
+ if(this.list.fireScroll.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.fireScroll.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.scrollUseCountdown += this.getCountdown();
+
+ // We burn the enemy !
+ var index = quest.getCharacterIndex();
+ index += 1; // We set the index to look just in front of the player
+ if(quest.things[index].type == "mob"){ // If it's a mob
+ quest.things[index].hp -= 25 + random.getRandomIntUpTo(10);
+ if(quest.things[index].hp < 0) quest.things[index] = quest.makeNoneThing();
+ }
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ acidRainScroll : function(){
+ if(yourself.end == false && this.list.acidRainScroll.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.acidRainScroll.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.scrollUseCountdown += this.getCountdown();
+
+ // We burn everyone
+ for(var i = 0; i < quest.things.length; i++){
+ if(quest.things[i].type == "mob" || quest.things[i].type == "character"){
+ quest.things[i].hp -= 6;
+ if(quest.things[i].type == "character" && quest.things[i].hp <= 0) quest.things[i].hp = 1;
+ if(quest.things[i].hp < 0) quest.things[i] = quest.makeNoneThing();
+ }
+ }
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ teleportScroll : function(){
+ // If we're not already at index 0
+ if(quest.things[0].type != "character" && this.list.teleportScroll.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.teleportScroll.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.scrollUseCountdown += this.getCountdown();
+
+ // We teleport !
+ var index = quest.getCharacterIndex();
+ quest.things[0] = quest.things[index];
+ quest.things[index] = quest.makeNoneThing();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ earthquakeScroll : function(){
+ if(yourself.end == false && this.list.earthquakeScroll.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.earthquakeScroll.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.scrollUseCountdown += this.getCountdown();
+
+ // We hit everyone
+ for(var i = 0; i < quest.things.length; i++){
+ if(quest.things[i].type == "mob" || quest.things[i].type == "character"){
+ quest.things[i].hp -= 12;
+ if(quest.things[i].type == "character" && quest.things[i].hp <= 0) quest.things[i].hp = 1;
+ if(quest.things[i].hp < 0) quest.things[i] = quest.makeNoneThing();
+ }
+ }
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ impInvocationScroll : function(){
+ var index = quest.getCharacterIndex();
+
+ // If the character isn't at the end of the land and there's nothing in front of him
+ if(index < quest.things.length-1 && quest.things[index+1].type == "none" && this.list.impInvocationScroll.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.impInvocationScroll.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.scrollUseCountdown += this.getCountdown();
+
+ // We invoke an int
+ quest.things[index+1] = quest.makeImp();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ invulnerability : function(){
+ if(this.list.invulnerability.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.invulnerability.nbrOwned -= 1;
+
+ // We set the countdown (40 ! because this potion is too awesome)
+ quest.potionUseCountdown += 40;
+
+ // We tell the quest that we are now in berserk mode
+ quest.beginInvulnerability();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ turtle : function(){
+ if(this.list.turtle.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.turtle.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.potionUseCountdown += this.getCountdown();
+
+ // We tell the quest that we are now in berserk mode
+ quest.beginTurtle();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ jelly : function(){
+ // We get the character index
+ var index = quest.getCharacterIndex();
+
+ // If the character isn't at the beginning of the land and there's nothing behind the character
+ if(index != 0 && quest.things[index - 1].type == "none" && this.list.jelly.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.jelly.nbrOwned -= 1;
+
+ // We place a jelly
+ quest.things[index-1] = this.makeJelly();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ seed : function(){
+ // We get the character index
+ var index = quest.getCharacterIndex();
+
+ // If the character isn't at the end of the land and there's nothing in front of the character
+ if(index < quest.things.length-1 && quest.things[index + 1].type == "none"){
+ // We decrement nbrOwned
+ this.list.seed.nbrOwned -= 1;
+
+ // We place a candy tree
+ quest.things[index+1] = this.makeCandyTree();
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ cloning : function(){
+ // We get the character index
+ var index = quest.getCharacterIndex();
+
+ // If the character isn't at the beginning of the land and there's nothing in front of the character
+ if(index != 0 && index < quest.things.length-1 && quest.things[index + 1].type == "none" && this.list.cloning.nbrOwned > 0){
+ // We decrement nbrOwned
+ this.list.cloning.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.potionUseCountdown += 100;
+
+ // We place a clone
+ quest.things[index+1] = this.makeClone(quest.things[index].hp, quest.things[index].max_hp);
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ superman : function(){
+ if(this.list.superman.nbrOwned > 0){
+ // We get the character's index
+ var index = quest.getCharacterIndex();
+
+ // We decrement nbrOwned
+ this.list.superman.nbrOwned -= 1;
+
+ // We set the countdown
+ quest.potionUseCountdown += this.getCountdown();
+
+ // We change the character text
+ quest.things[index].text = "(o-";
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ gmooh : function(){
+ if(this.list.gmooh.nbrOwned > 0){
+ // We tell the quest that we're using a gmooh potion, then when quest.move will be executed, our gmoohEffect() function will be called
+ quest.gmooh = true;
+
+ // We delete all tired time
+ quest.setTiredTime(0);
+ quest.setTiredFound(0);
+
+ // We update the quest and the potions on page
+ quest.updateOnPage();
+ this.updateOnPage();
+ }
+ },
+
+ // When this function is called, quest.stop() was done just before, so we can launch a new quest if we want ;)
+ gmoohEffect : function(){
+ // We decrement nbrOwned
+ this.list.gmooh.nbrOwned -= 1;
+
+ quest.setTiredTime(0);
+
+ switch(random.getRandomIntUpTo(3)){
+ case 0:
+ quest.begin(false, land.getLandIndexFromName("The peaceful forest"));
+ break;
+ case 1:
+ quest.begin(false, land.getLandIndexFromName("cowLevel"));
+ break;
+ case 2:
+ quest.begin(false, land.getLandIndexFromName("sea"));
+ break;
+ case 3:
+ quest.begin(false, land.getLandIndexFromName("desert"));
+ break;
+ }
+ }
+
+};
diff --git a/static/candies/scripts/quest.js b/static/candies/scripts/quest.js
new file mode 100755
index 00000000..0a9dcdc3
--- /dev/null
+++ b/static/candies/scripts/quest.js
@@ -0,0 +1,476 @@
+var quest = {
+
+ // Variables
+ currentLandIndex : 0, // Index of the current land in land.list
+ maxLandOrder : -1, // Max land order we achieved for the moment
+ candiesFound : 0, // Number of candies found during a quest
+ speed : 0, // Speed of the character during a quest
+ things : [], // Array containing all the things present in a quest
+ tiredTime : 0, // Number of seconds we need to spend before doing another quest
+ tiredFound : 0, // Number of seconds we will need to wait after finishing the current quest
+ potionUseCountdown : 0, // Number of movements we have to wait before using another potion
+ scrollUseCountdown : 0, // Same thing for scrolls
+ escaping : false, // If true, it means we are escaping from the quest
+ gmooh : false,
+ berserk : false, // If true, we're in berserk mode
+ berserkCountdown : 0, // Number of cycles we still have to stay in berserk mode
+ invulnerability : false, // If true, we're invincible
+ invulnerabilityCountdown : 0, // Number of cycles we still have to stay as invincible
+ turtle : false, // If true, we're a turtle
+ turtleCountdown : 0, // Number of cycles we still have to stay as a turtle
+ weAreQuestingRightNow : false, // True if we're making a quest right now
+ characterSpeed : 1, // Speed of the character : if = 2 for example, the character will take two cycles to move. This variable can be reduce by being a turtle
+ characterSpeedStep : 1, // Used to apply the characterSpeed var
+
+ onloadAfter : function(){
+ this.setMaxLandOrder(0);
+ },
+
+ setMaxLandOrder : function(value){
+ if(value > this.maxLandOrder){
+ this.maxLandOrder = value; // We change the value
+ land.updateListOnPage(quest.maxLandOrder); // And we try to update the quest list on the html page, in case a new quest was unlocked
+ }
+ },
+
+ begin : function(getLandFromList, landIndex){
+ // Disable button
+ htmlInteraction.disableButton("quest_button");
+
+ // First thing to do !
+ this.weAreQuestingRightNow = true;
+
+ // If we have to get the land index from the list on the html page
+ if(getLandFromList == true){
+ // We get the index in land.list of the current land selected in the html list
+ var landNameInHtmlList = htmlInteraction.getElement("quest_destination").options[htmlInteraction.getElement("quest_destination").selectedIndex].text;
+ this.currentLandIndex = land.getLandIndexFromName(landNameInHtmlList);
+ }
+ // Else, we use the index given in the parameters
+ else{
+ this.currentLandIndex = landIndex;
+ }
+
+ // We show the quest panel
+ htmlInteraction.setElementVisibility("quest", true);
+ htmlInteraction.setElementVisibility("quest_potions_countdowns", true);
+
+ // We empty the things array and put none things in it
+ this.things = this.fillWithNoneThings();
+
+ // We add the character
+ if(land.ponyTime == false)
+ this.things[0] = {type:"character", text:"\\o/", max_hp:this.getCharacterMaxHp(), hp:this.getCharacterMaxHp(), weapon:(sword.name), description:"You"};
+ else
+ this.things[0] = {type:"character", text:"PON", max_hp:this.getCharacterMaxHp(), hp:this.getCharacterMaxHp(), weapon:(sword.name), description:"You"};
+
+ // We set the speed
+ this.speed = this.getSpeed();
+
+ // We set the potion & scroll use countdown
+ this.potionUseCountdown = 0;
+ this.scrollUseCountdown = 0;
+
+ // Not escaping at first
+ this.escaping = false;
+
+ // Not using gmooh potion at first
+ this.gmooh = false;
+
+ // Not in berserk mode at first
+ this.berserk = false;
+ this.berserkCountdown = 0;
+ this.speed = this.getSpeed();
+
+ // Not invincible at first
+ this.invulnerability = false;
+ this.invulnerabilityCountdown = 0;
+
+ // Not turtle at first
+ this.turtle = false;
+ this.turtleCountdown = 0;
+
+ // Speed = 1 at first and the step = 1 too
+ this.characterSpeed = 1;
+ this.characterSpeedStep = 1;
+
+ // Load the current land
+ land.load();
+
+ // Update the quest and the potions on page
+ this.updateOnPage();
+ potions.updateOnPage();
+
+ // Set a timeout for the next quest movement
+ window.setTimeout(this.move.bind(this), this.speed);
+ },
+
+ updateOnPage : function(){
+ // Variables declaration
+ var text;
+
+ // Land
+ text = land.getText();
+ text += "\n";
+
+ // Status
+ text += status2.getText();
+ text += "\n";
+
+ // Drops
+ text += drops.getText();
+
+ // Draw text
+ htmlInteraction.setInnerHtml("quest", text);
+ },
+
+ getCharacterMaxHp : function(){
+ return 100 + Math.floor(Math.pow(candies.nbrEaten, 0.4)*2.1); // This function means ~ one day of candies eaten at 1cnd/s = +200 hp
+ },
+
+ getSpeed : function(){
+ if(objects.list.boots.have && this.berserk) return 125;
+ if(objects.list.boots.have || this.berserk) return 250;
+
+ return 500;
+ },
+
+ getCharacterIndex : function(){
+ for(i = 0; i < this.things.length; i++){
+ if(this.things[i].type == "character") return i;
+ }
+ },
+
+ move : function(){
+ // If we're not escaping, we don't stop the quest
+ if(this.escaping == false && this.gmooh == false){
+ for(var index = 0; index < this.things.length; index++){
+ if(this.things[index].type == "character" || this.things[index].type == "ally" || this.things[index].type == "trap"){
+ // If we are at the end of the quest
+ if(index + 1 == this.things.length){
+ // If we're the character
+ if(this.things[index].type == "character"){
+ // We set a timeout to the winning function and we return
+ window.setTimeout(this.won.bind(this), 3000);
+ return;
+ }
+ // Else, we're just an ally or a trap
+ else{
+ // We disappear
+ quest.things[index] = quest.makeNoneThing();
+ }
+ }
+ // Else, we move ourselves
+ else{
+ // If there's nothing in front of us and we're not a trap, we just move
+ if(this.things[index].type != "trap" && this.things[index + 1].type == "none"){
+ if(this.characterSpeedStep >= this.characterSpeed){
+ this.characterSpeedStep = 1; // We set the step back to 1
+ this.things[index + 1] = this.things[index];
+ this.things[index] = this.makeNoneThing();
+ index += 1; // We increment the index to avoid re evaluating the same thing just after
+ }
+ else{
+ this.characterSpeedStep += 1; // We increment the step
+ }
+ }
+ // Else, we try to fight
+ else{
+ // If the thing in front of us is a mob or a trap (and we're not one..), we fight
+ if(this.things[index + 1].type == "mob" || (this.things[index + 1].type == "trap" && this.things[index].type != "trap")){
+ if(this.fight(index, index + 1) == true) return;
+ }
+ }
+ }
+ }
+ }
+
+ // We set the timeout to move again
+ window.setTimeout(this.move.bind(this), this.speed);
+
+ // We decrement the potion use countdown
+ if(this.potionUseCountdown > 0){
+ this.potionUseCountdown -= 1;
+ if(this.potionUseCountdown == 0){
+ potions.updateOnPage();
+ }
+ else potions.updateCountdownOnPage();
+ }
+
+ // Same thing for the scroll use countdown
+ if(this.scrollUseCountdown > 0){
+ this.scrollUseCountdown -= 1;
+ if(this.scrollUseCountdown == 0){
+ potions.updateOnPage();
+ }
+ else potions.updateCountdownOnPage();
+ }
+
+ // We decrement the berserk mode countdown
+ if(this.berserkCountdown > 0){
+ this.berserkCountdown -= 1;
+ if(this.berserkCountdown == 0) this.stopBerserk();
+ potions.updateCountdownOnPage();
+ }
+
+ // We decrement the invulnerability mode countdown
+ if(this.invulnerabilityCountdown > 0){
+ this.invulnerabilityCountdown -= 1;
+ if(this.invulnerabilityCountdown == 0) this.stopInvulnerability();
+ potions.updateCountdownOnPage();
+ }
+
+ // We decrement the turtle mode countdown
+ if(this.turtleCountdown > 0){
+ this.turtleCountdown -= 1;
+ if(this.turtleCountdown == 0) this.stopTurtle();
+ potions.updateCountdownOnPage();
+ }
+
+ // We make the land move too
+ if(land.list[this.currentLandIndex].moveFunction != undefined){
+ land.list[this.currentLandIndex].moveFunction();
+ }
+
+ // Horn bonus
+ if(objects.list.magicalHorn.have){
+ this.applyMagicalHornBonus();
+ }
+
+ // We update on page
+ this.updateOnPage();
+ }
+ // Else we're escaping : we stop the quest
+ else if(this.escaping){
+ this.stop();
+ }
+ // Else if we're using a gmooh potion
+ else if(this.gmooh){
+ this.stop();
+ potions.gmoohEffect();
+ }
+ },
+
+ applyMagicalHornBonus : function(){
+ var index = this.getCharacterIndex();
+
+ // If we're not dead
+ if(this.things[index].hp > 0){
+ this.things[index].hp += 3;
+ if(this.things[index].hp > this.things[index].max_hp) this.things[index].hp = this.things[index].max_hp;
+ }
+ },
+
+ fight : function(index1, index2){
+ // We launch a fight between us and the mob if the mob still have some hp (he may lose its hp because of a scroll)
+ if(this.things[index2].hp > 0) damage.makeTwoQuestThingsFighting(index1, index2);
+
+ // Check for deads
+ if(this.checkIfDead(index1, index2) == true) return true;
+ if(this.checkIfDead(index2, index1) == true) return true;
+
+ return false;
+ },
+
+ checkIfDead : function(index, indexKiller){
+ // If we're dead
+ if(this.things[index].hp <= 0){
+ // If we're the character
+ if(this.things[index].type == "character"){
+ this.updateOnPage(); // We update on page
+ window.setTimeout(this.stop.bind(this), 5000); // We set the timeout to stop the quest
+ return true; // We quit
+ }
+ // Else, we're just an ally or a trap
+ else if(this.things[index].type == "ally" || this.things[index].type == "trap"){
+ // We disappear
+ if(this.things[index].drops != []) drops.getAllDropsFromList(this.things[index].drops); // We gain the drops of the defeated ally or trap
+ quest.things[index] = quest.makeNoneThing();
+ }
+ // Else, we're a mob
+ else if(this.things[index].type == "mob" && (this.things[index].text != "\\o/" || yourself.canSurpass == true)){
+ drops.getAllDropsFromList(this.things[index].drops); // We gain the drops of the defeated mob
+ this.things[index] = this.makeNoneThing(); // We remove the mob
+
+ // If we we were killed by the character
+ if(this.things[indexKiller].type == "character"){
+ // Sword of Summoning bonus : we may spawn something here
+ if(sword.name == "Sword of Summoning" || sword.name == "Sword of Liflamesummoning"){
+ sword.summonHere(index);
+ }
+ // Sword of Life : we gain life
+ if(sword.name == "Sword of Life" || sword.name == "Sword of Liflamesummoning"){
+ this.things[indexKiller].hp += sword.specialPower + 1;
+ if(this.things[indexKiller].hp > this.things[indexKiller].max_hp) this.things[indexKiller].hp = this.things[indexKiller].max_hp;
+ }
+ }
+ }
+ }
+
+ return false;
+ },
+
+ beginBerserk : function(){
+ this.berserk = true;
+ this.berserkCountdown = 25 + random.getRandomIntUpTo(10);
+ this.speed = this.getSpeed();
+ this.things[this.getCharacterIndex()].text = "O_O";
+ },
+
+ stopBerserk : function(){
+ this.berserk = false;
+ this.speed = this.getSpeed();
+ this.things[this.getCharacterIndex()].text = "\\o/";
+ },
+
+ beginInvulnerability : function(){
+ this.invulnerability = true;
+ this.invulnerabilityCountdown = 15;
+ this.things[this.getCharacterIndex()].text = "GOD";
+ },
+
+ stopInvulnerability : function(){
+ this.invulnerability = false;
+ this.things[this.getCharacterIndex()].text = "\\o/";
+ },
+
+ beginTurtle : function(){
+ this.turtle = true;
+ this.turtleCountdown = 30;
+ this.things[this.getCharacterIndex()].text = "TUR";
+ this.characterSpeed = 3; // We reduce the speed !
+ },
+
+ stopTurtle : function(){
+ this.turtle = false;
+ this.things[this.getCharacterIndex()].text = "\\o/";
+ this.characterSpeed = 1; // The speed goes back to its normal state !
+ },
+
+ won : function(){
+ // won ?
+ if(land.getLandIndexFromName("Developper's computer") == quest.currentLandIndex){
+ developperComputer.setWon(true);
+ inventory.updateOnPage();
+ }
+
+ // Drops
+ drops.gainDrops();
+
+ // We may enable a new destination, we store the drop-down list
+ var list = htmlInteraction.getElement("quest_destination");
+
+ // We change the max land order : it's the order of the just finnished quest + 1
+ this.setMaxLandOrder(land.list[this.currentLandIndex].order + 1);
+
+ // We stop the quest
+ this.stop();
+ },
+
+ stop : function(){
+ // Enable button
+ htmlInteraction.enableButton("quest_button");
+
+ // First thing to do !
+ this.weAreQuestingRightNow = false;
+
+ // Get the character index
+ var index = this.getCharacterIndex();
+
+ // No more quest panel or potions shown
+ htmlInteraction.setInnerHtml("quest", "");
+ htmlInteraction.setInnerHtml("quest_potions_countdowns", "");
+
+ // We re-enable home buttons
+ //buttons.enableHomeButtons();
+
+ // We update the potions on page
+ potions.updateOnPage();
+
+ // We're tired after this quest
+ if(this.things[index].hp < this.things[index].max_hp) this.setTiredFound(this.tiredFound + 200 * (1 - (this.things[index].hp / this.things[index].max_hp)));
+ if(this.escaping == false) this.setTiredTime(Math.floor(this.tiredFound));
+
+ // Nothing found anymore
+ this.setCandiesFound(0);
+ this.setTiredFound(0);
+ for(obj in objects.list) objects.list[obj].found = false;
+ },
+
+ defineMood : function(){
+ if(this.tiredTime == 0) htmlInteraction.setInnerHtml("mood", "You're all set! Ready for fighting!");
+ else htmlInteraction.setInnerHtml("mood", "You're tired. You have to wait before doing another quest. Waiting time: " + this.tiredTime + "
");
+ htmlInteraction.setElementVisibility("mood", true);
+ },
+
+ setCandiesFound : function(value){
+ this.candiesFound = value;
+ },
+
+ setTiredTime : function(value){
+ if(value < 0) value = 0;
+
+ this.tiredTime = value;
+ this.defineMood();
+ buttons.checkQuestTiredTime();
+ },
+
+ setTiredFound : function(value){
+ this.tiredFound = value;
+ },
+
+ makeNoneThing : function(){
+ return {type:"none", text:"___"};
+ },
+
+ makeBasicChest : function(){
+ return land.createMob("CHS", 80, 80, "none", "A chest! Very rare.", [drops.createDrop("candies", 300 + random.getRandomIntUpTo(500)), drops.createDrop("object", "key", true), drops.createDrop("object", "boots", random.oneChanceOutOf(3)), drops.createDrop("object", "swampMap", random.oneChanceOutOf(3)), drops.createDrop("object", "hutMap", random.oneChanceOutOf(3))]);
+ },
+
+ makeOpenChest : function(){
+ return land.createMob("CHS", 1, 1, "none", "An open chest, full of candies!", [drops.createDrop("candies", 6000 + random.getRandomIntUpTo(2000))]);
+ },
+
+ makeImp : function(){
+ var hp = 15 + random.getRandomIntUpTo(10);
+ return land.createAlly("IMP", hp, hp, "its whole body", "An imp.", []);
+ },
+
+ makeOrc : function(){
+ return land.createAlly("ORC", 30, 30, "bludgeon", "An orc. It looks stupid.", []);
+ },
+
+ makeDraugr : function(){
+ return land.createAlly("DRG", 35, 35, "various bones", "A draugr. It seems to be dead, but it's still moving..", []);
+ },
+
+ makeChupacabra : function(){
+ return land.createAlly("CBA", 30, 30, "fangs", "A chupacabra. A real goat sucker!", []);
+ },
+
+ makeGolem : function(){
+ return land.createAlly("GOL", 100, 100, "rock", "A golem. Solid, solid golem.", []);
+ },
+
+ makeChimera : function(){
+ var hp = 50 + random.getRandomIntUpTo(7);
+ return land.createAlly("CHI", hp, hp, "fire", "A chimera: lion, serpent and goat at the same time.", []);
+ },
+
+ makeCandyMonster : function(){
+ var hp = 80 + 5*sword.specialPower;
+
+ return land.createAlly("CND", hp, hp, "exploding candies", "A candy monster. He throws candies on his enemies.", []);
+ },
+
+ makeFakeCharacter : function(){
+ return land.createFakeCharacter();
+ },
+
+ fillWithNoneThings : function(){
+ var things = [];
+ for(var i = 0; i < land.list[this.currentLandIndex].size; i++) things.push(this.makeNoneThing());
+ return things;
+ }
+
+};
diff --git a/static/candies/scripts/random.js b/static/candies/scripts/random.js
new file mode 100755
index 00000000..086b133f
--- /dev/null
+++ b/static/candies/scripts/random.js
@@ -0,0 +1,43 @@
+var random = {
+
+ flipACoin : function(){
+ if(Math.random() < 0.5) return true;
+ return false;
+ },
+
+ oneChanceOutOf : function(n){
+ if(this.getRandomIntUpTo(n - 1) == 0) return true;
+ else return false;
+ },
+
+ getRandomFloat : function(){
+ return Math.random();
+ },
+
+ pickRandomly : function(array){
+ return array[Math.floor(Math.random()*array.length)];
+ },
+
+ getRandomIntUpTo : function(n){
+ return Math.floor(Math.random()*(n+1));
+ },
+
+ getRandomLetter : function(){
+ var possible = "abcdefghijklmnopqrstuvwxyz";
+
+ return possible.charAt(Math.floor(this.getRandomFloat() * possible.length));
+ },
+
+ pure : function(){
+ return Math.floor(Math.pow(10, random.getRandomIntUpTo(100)) * random.getRandomFloat());
+ },
+
+ pure2 : function(){
+ switch(random.getRandomIntUpTo(2)){
+ case 0: return Math.floor(Math.pow(10, random.getRandomIntUpTo(100)) * random.getRandomFloat()); break;
+ case 1: return -Math.floor(Math.pow(10, random.getRandomIntUpTo(100)) * random.getRandomFloat()); break;
+ case 2: return "bug"; break;
+ }
+ },
+
+};
diff --git a/static/candies/scripts/save.js b/static/candies/scripts/save.js
new file mode 100755
index 00000000..43696010
--- /dev/null
+++ b/static/candies/scripts/save.js
@@ -0,0 +1,114 @@
+var code = "";
+
+function save() {
+ $.ajax({
+ type: "POST",
+ url: "scripts/save.php",
+ data: {
+ swordName : sword.name,
+ swordSpecialSword : sword.specialSword,
+ swordSpecialPower : sword.specialPower,
+ candiesNbrOwned : candies.nbrOwned,
+ candiesNbrThrown : candies.nbrThrown,
+ candiesNbrEaten : candies.nbrEaten,
+ candiesNbrTotal : candies.nbrTotal,
+ candiesCandiesPerSecond : candies.candiesPerSecond,
+ candiesConverterActivated : candiesConverter.activated,
+ cauldronBookPage : cauldron.bookPage,
+ cauldronCandies : cauldron.candiesInTheCauldron,
+ cauldronLollipops : cauldron.lollipopsInTheCauldron,
+ chocolateBarsNbrOwned : chocolateBars.nbrOwned,
+ farmLollipopsPlanted : farm.lollipopsPlanted,
+ farmCurrentFlagIndex : farm.currentFlagIndex,
+ farmPlantingButtonsStep : farm.plantingButtonsStep,
+ forgeStep : forge.step,
+ shopLollipopsButtonsShown : shop.buy10LollipopsButtonShown,
+ shopShown : shop.shown,
+ shopTicklingStep : shop.ticklingStep,
+ shopClickingOnLollipopStep : shop.clickingOnLollipopStep,
+ hutStep : hut.step,
+ hutSpeech : hut.speech,
+ inventoryMagicianHatLetter : inventory.magicianHatLetter,
+ lollipopsNbrOwned : lollipops.nbrOwned,
+ lollipopsNbrInStock : lollipops.nbrInStock,
+ lollipopsNbrBought : lollipops.nbrBought,
+ mainNbrOfSecondsSinceLastMinInterval : main.nbrOfSecondsSinceLastMinInterval,
+ mainNbrOfSecondsSinceLastHourInterval : main.nbrOfSecondsSinceLastHourInterval,
+ mainNbrOfSecondsSinceLastDayInterval : main.nbrOfSecondsSinceLastDayInterval,
+ mountGoblinBasicChestProbability : mountGoblin.basicChestProbability,
+ peacefulForestBasicChestProbability : peacefulForest.basicChestProbability,
+ peacefulForestPoniesEncountered : peacefulForest.poniesEncountered,
+ objectsHaveObjectKey : objects.list.key.have,
+ objectsHaveObjectHutMap : objects.list.hutMap.have,
+ objectsHaveObjectWellMap : objects.list.wellMap.have,
+ objectsHaveObjectSwampMap : objects.list.swampMap.have,
+ objectsHaveObjectBoots : objects.list.boots.have,
+ objectsHaveObjectMagicianHat : objects.list.magicianHat.have,
+ objectsHaveObjectPinkRing : objects.list.pinkRing.have,
+ objectsHaveObjectForgeMap : objects.list.forgeMap.have,
+ objectsHaveObjectCandiesConverter : objects.list.candiesConverter.have,
+ objectsHaveObjectPlateArmour : objects.list.plateArmour.have,
+ objectsHaveObjectCauldron : objects.list.cauldron.have,
+ objectsHaveObjectMagicalHorn : objects.list.magicalHorn.have,
+ objectsHaveObjectHornOfPlenty : objects.list.hornOfPlenty.have,
+ objectsHaveObjectOldAmulet : objects.list.oldAmulet.have,
+ potionsShownHealth : potions.list.health.shown,
+ potionsShownEscape : potions.list.escape.shown,
+ potionsShownBerserk : potions.list.berserk.shown,
+ potionsShownFireScroll : potions.list.fireScroll.shown,
+ potionsShownAcidRainScroll : potions.list.acidRainScroll.shown,
+ potionsShownTeleportScroll : potions.list.teleportScroll.shown,
+ potionsShownEarthquakeScroll : potions.list.earthquakeScroll.shown,
+ potionsShownImpInvocationScroll : potions.list.impInvocationScroll.shown,
+ potionsShownMajorHealth : potions.list.majorHealth.shown,
+ potionsShownInvulnerability : potions.list.invulnerability.shown,
+ potionsShownTurtle : potions.list.turtle.shown,
+ potionsShownJelly : potions.list.jelly.shown,
+ potionsShownSeed : potions.list.seed.shown,
+ potionsShownCloning : potions.list.cloning.shown,
+ potionsShownSuperman : potions.list.superman.shown,
+ potionsShownGmooh : potions.list.gmooh.shown,
+ potionsNbrOwnedHealth : potions.list.health.nbrOwned,
+ potionsNbrOwnedEscape : potions.list.escape.nbrOwned,
+ potionsNbrOwnedBerserk : potions.list.berserk.nbrOwned,
+ potionsNbrOwnedFireScroll : potions.list.fireScroll.nbrOwned,
+ potionsNbrOwnedAcidRainScroll : potions.list.acidRainScroll.nbrOwned,
+ potionsNbrOwnedTeleportScroll : potions.list.teleportScroll.nbrOwned,
+ potionsNbrOwnedEarthquakeScroll : potions.list.earthquakeScroll.nbrOwned,
+ potionsNbrOwnedImpInvocationScroll : potions.list.impInvocationScroll.nbrOwned,
+ potionsNbrOwnedMajorHealth : potions.list.majorHealth.nbrOwned,
+ potionsNbrOwnedInvulnerability : potions.list.invulnerability.nbrOwned,
+ potionsNbrOwnedTurtle : potions.list.turtle.nbrOwned,
+ potionsNbrOwnedJelly : potions.list.jelly.nbrOwned,
+ potionsNbrOwnedSeed : potions.list.seed.nbrOwned,
+ potionsNbrOwnedCloning : potions.list.cloning.nbrOwned,
+ potionsNbrOwnedSuperman : potions.list.superman.nbrOwned,
+ potionsNbrOwnedGmooh : potions.list.gmooh.nbrOwned,
+ questMaxLandOrder : quest.maxLandOrder,
+ questTiredTime : quest.tiredTime,
+ spellsFasterCandiesFibo1 : spells.fasterCandiesFiboPrev,
+ spellsFasterCandiesFibo2 : spells.fasterCandiesFiboCurr,
+ swampStep : swamp.step,
+ tabsAnimation : tabs.animation,
+ wishingWellSpeech : wishingWell.speech,
+ wishingWellStep : wishingWell.step,
+ yourselfCanSurpass : yourself.canSurpass,
+ developperComputerWon : developperComputer.won
+ },
+ success: function(msg){
+ if(msg=="error"){
+
+ alert("There was a problem while saving. Please go nicely bother Scrabble or try again later. :-(");
+ $("span#save").html("");
+
+ }else{
+
+ code = msg.substring(0,5);
+ alert('You saved successfully under the code "' + msg + '". Write this down somewhere, you will need it later!');
+ $("span#save").html(" You can also bookmark this link to load the save.");
+
+ }
+ }
+ });
+ return false;
+}
diff --git a/static/candies/scripts/sea.js b/static/candies/scripts/sea.js
new file mode 100755
index 00000000..2a73b5e8
--- /dev/null
+++ b/static/candies/scripts/sea.js
@@ -0,0 +1,68 @@
+var sea = {
+
+ // Variables
+ size : 25,
+
+ // Functions
+ onload : function(){
+ land.addLand("sea", this.size, -1, this.load.bind(this), this.getText.bind(this));
+ },
+
+ load : function(){
+
+ },
+
+ getText : function(){
+ // Get the character position
+ var index = quest.getCharacterIndex();
+
+ // Create the text
+ var text = " \"The sea\"\n\n\n";
+
+ for(var i = 0; i < index; i++){
+ text += " ";
+ }
+ text += " _\n";
+
+ for(var i = 0; i < index; i++){
+ text += " ";
+ }
+ text += " /|\\\n";
+
+ for(var i = 0; i < index; i++){
+ text += " ";
+ }
+ text += " /_|_\\\n";
+
+ for(var i = 0; i < index; i++){
+ text += " ";
+ }
+ text += " ____|\\o/_\n";
+
+ for(var i = 0; i < index; i++){
+ text += " ";
+ }
+ text += " \\_______/\n";
+
+ for(var i = 0; i < this.size + 2; i++){
+ text += " ~ ";
+ }
+ text += "\n ";
+
+ for(var i = 0; i < this.size + 1; i++){
+ text += " ~ ";
+ }
+
+ return text;
+ }
+
+/*
+ _
+ /|\
+ /_|_\
+ ____|\o/_
+ \_______/
+
+*/
+
+};
diff --git a/static/candies/scripts/shop.js b/static/candies/scripts/shop.js
new file mode 100755
index 00000000..ba65db14
--- /dev/null
+++ b/static/candies/scripts/shop.js
@@ -0,0 +1,183 @@
+var shop = {
+
+ // Variables
+ buy10LollipopsButtonShown : false, // True if the buy 10 lollipops button should be shown
+ shown : false, // True if the shop is currently shown
+ ticklingStep : 0, // Tickling step (increase when we click on the merchant's hat
+ clickingOnLollipopStep : 0, // Clicking on lollipop step (increase when we clicked on the top of the lollipop sold at the shop)
+ oneLollipopPrice : 0, // Price of one lollipop, calculated depending on the clicking on lollipop step
+ tenLollipopsPrice : 0, // Price of ten lollipops, calculated the same way as above
+ currentSwordButtonId : "none", // Contains the id of the current sword buying button
+ currentSwordPrice : 0, // Contains the price of the current sword being sold by the merchant
+
+ // Functions
+ onload : function(){
+ lollipops.delivery(); // The merchant must have some lollipops in stock at the beginning, so we make a delivery
+ this.setClickingOnLollipopStep(0); // This also set the lollipops price !
+ },
+
+ check : function(){
+ if(candies.nbrOwned >= this.oneLollipopPrice){
+ this.setShown(true);
+ }
+ if(candies.nbrOwned >= 100){
+ // If we don't have any sword and there's no sword to sell yet, we show the wooden sword
+ if(sword.name == "none" && this.currentSwordButtonId == "none"){
+ this.showProduct("wooden_sword");
+ }
+ }
+ },
+
+ setBuy10LollipopsButtonShown : function(value){
+ this.buy10LollipopsButtonShown = value;
+ },
+
+ clickedOnHat : function(){
+ switch(this.ticklingStep){
+ case 0:
+ this.setMerchantSpeech("Hey! You touched my hat!");
+ break;
+ case 1:
+ this.setMerchantSpeech("Stop that, stop that! You're tickling me!");
+ break;
+ case 2:
+ this.setMerchantSpeech("Hahahaha! I'm so ticklish!");
+ break;
+ case 3:
+ this.setMerchantSpeech("Listen, listen: I will give you 100 candies! But stop that please!");
+ candies.setNbrOwned(candies.nbrOwned + 100);
+ break;
+ }
+
+ this.setTicklingStep(this.ticklingStep + 1);
+ },
+
+ setTicklingStep : function(value){
+ this.ticklingStep = value;
+ },
+
+ setClickingOnLollipopStep : function(value){
+ this.clickingOnLollipopStep = value;
+
+ // Set the buttons value if the step is 0 or the price is reducing or is reduced
+ if(this.clickingOnLollipopStep <= 4){
+ this.oneLollipopPrice = 60;
+ this.tenLollipopsPrice = 500;
+ htmlInteraction.setInnerHtml("buy_1_lollipop", "Buy 1 lollipop (60 candies)");
+ htmlInteraction.setInnerHtml("buy_10_lollipops", "Buy 10 lollipops (500 candies)");
+ }
+ else if(this.clickingOnLollipopStep >= 5 && this.clickingOnLollipopStep < 15){
+ this.oneLollipopPrice = 60 - (this.clickingOnLollipopStep - 4);
+ this.tenLollipopsPrice = 500 - (this.clickingOnLollipopStep - 4) * 5;
+ htmlInteraction.setInnerHtml("buy_1_lollipop", "Buy 1 lollipop (" + this.oneLollipopPrice + " candies)");
+ htmlInteraction.setInnerHtml("buy_10_lollipops", "Buy 10 lollipops (" + this.tenLollipopsPrice + " candies)");
+ }
+ else{
+ this.oneLollipopPrice = 60 - (14 - 4);
+ this.tenLollipopsPrice = 500 - (14 - 4) * 5;
+ htmlInteraction.setInnerHtml("buy_1_lollipop", "Buy 1 lollipop (" + this.oneLollipopPrice + " candies)");
+ htmlInteraction.setInnerHtml("buy_10_lollipops", "Buy 10 lollipops (" + this.tenLollipopsPrice + " candies)");
+ }
+ },
+
+ clickedOnLollipop : function(){
+ this.setClickingOnLollipopStep(this.clickingOnLollipopStep + 1);
+
+ // Possibly change the merchant speech
+ switch(this.clickingOnLollipopStep){
+ case 1:
+ this.setMerchantSpeech("Hey! Don't touch the products!");
+ break;
+ case 2:
+ this.setMerchantSpeech("Seriously, don't touch this lollipop.");
+ break;
+ case 3:
+ this.setMerchantSpeech("Don't touch it! Other customers may lick it after that, that's gross!");
+ break;
+ case 4:
+ this.setMerchantSpeech("Stop now or I'll be forced to do something.");
+ break;
+ case 15:
+ this.setMerchantSpeech("I can't make a lower price... Please stop.");
+ break;
+ }
+
+ if(this.clickingOnLollipopStep >= 5 && this.clickingOnLollipopStep < 15){
+ this.setMerchantSpeech("Okay, okay, I'll lower the price, but stop touching it!");
+ }
+ },
+
+ showProduct : function(id){
+ switch(id){
+ // If it's a special product
+ case "wooden_sword":
+ htmlInteraction.setInnerHtml("sword_with_button", sword.asciiWoodenSwordWithButton);
+ this.currentSwordButtonId = "buy_wooden_sword";
+ this.currentSwordPrice = 100;
+ break;
+ case "copper_sword":
+ htmlInteraction.setInnerHtml("sword_with_button", sword.asciiCopperSwordWithButton);
+ this.currentSwordButtonId = "buy_copper_sword";
+ this.currentSwordPrice = 300;
+ break;
+ case "iron_sword":
+ htmlInteraction.setInnerHtml("sword_with_button", sword.asciiIronSwordWithButton);
+ this.currentSwordButtonId = "buy_iron_sword";
+ this.currentSwordPrice = 500;
+ break;
+ case "silver_sword":
+ htmlInteraction.setInnerHtml("sword_with_button", sword.asciiSilverSwordWithButton);
+ this.currentSwordButtonId = "buy_silver_sword";
+ this.currentSwordPrice = 1000;
+ break;
+ case "diamond_sword":
+ htmlInteraction.setInnerHtml("sword_with_button", sword.asciiDiamondSwordWithButton);
+ this.currentSwordButtonId = "buy_diamond_sword";
+ this.currentSwordPrice = 2000;
+ break;
+ // Else, we just show the html element corresponding to the received id
+ default:
+ htmlInteraction.setElementVisibility(id, true);
+ htmlInteraction.setElementDisplay(id, "block");
+ break;
+ }
+ },
+
+ show : function(){
+ // We show the shop
+ if(htmlInteraction.isElementVisible("shop") == false){ // If the shop isn't already visible
+ htmlInteraction.setElementVisibility("shop", true);
+ this.setMerchantSpeech(" Welcome to Uncle Snake's Candy Emporium! I would do anything for candies. My lollipops are delicious!");
+ }
+
+ // And the lollipop we can buy :)
+ this.showProduct("lollipop");
+ },
+
+ setShown : function(value){
+ // If the new value is true but it was false before, we show the shop
+ if(value == true && this.shown == false)
+ this.show();
+
+ // We change the value
+ this.shown = value;
+ },
+
+ hideProduct : function(id){
+ // If it's a special product
+ if(id == "sword"){
+ this.currentSwordButtonId = "none";
+ htmlInteraction.setInnerHtml("sword_with_button", "");
+ }
+ // Else
+ else{
+ htmlInteraction.setElementVisibility(id, false);
+ htmlInteraction.setElementDisplay(id, "none");
+ }
+ },
+
+ setMerchantSpeech : function(text){
+ htmlInteraction.setInnerHtml("merchant_speech", speech.makeSpeechFromText(text, 20, " "));
+ }
+
+};
diff --git a/static/candies/scripts/speech.js b/static/candies/scripts/speech.js
new file mode 100755
index 00000000..10c676af
--- /dev/null
+++ b/static/candies/scripts/speech.js
@@ -0,0 +1,47 @@
+var speech = {
+
+ makeLineFromWords : function(words, size){
+ var line = words[0];
+ var length = words[0].length;
+ for(var i = 1; i < words.length; i++){
+ line += " " + words[i];
+ length += 1 + words[i].length;
+ }
+ var spaces = Math.floor((size - length)/2);
+ for(var i = 0; i < spaces; i++){
+ line = " " + line + " ";
+ length += 2;
+ }
+ if(length == (size-1)) line += " ";
+ return line;
+ },
+
+ makeSpeechFromText : function(text, size, spaces_add){
+ var words = text.split(" ");
+ var current_line_size = 0;
+ var current_line = [];
+ var final_text = "";
+ var a_line_has_been_added = false;
+ for(var i = 0; i < words.length; i++){
+ current_line_size += 1 + words[i].length;
+ if(current_line_size > size){ // If, with this word, the line is too big
+ if(a_line_has_been_added == true) final_text += spaces_add + " ";
+ final_text += this.makeLineFromWords(current_line, size) + "\n"; // We add the current line to the final text
+ a_line_has_been_added = true;
+ current_line_size = words[i].length;
+ current_line = [];
+ current_line.push(words[i]);
+ }
+ else{
+ current_line.push(words[i]);
+ }
+ }
+ if(current_line.length != 0){
+ if(a_line_has_been_added == true) final_text += spaces_add + " ";
+ final_text += this.makeLineFromWords(current_line, size);
+ }
+ return spaces_add + "\"" + final_text + "\"";
+ }
+
+};
+
diff --git a/static/candies/scripts/spells.js b/static/candies/scripts/spells.js
new file mode 100755
index 00000000..6dd94fcd
--- /dev/null
+++ b/static/candies/scripts/spells.js
@@ -0,0 +1,97 @@
+var spells = {
+
+ // Variables
+ list : [],
+ fasterCandiesFiboPrev : 1,
+ fasterCandiesFiboCurr : 2,
+
+ // Functions
+ onload : function(){
+ // We add the spells
+ this.addSpell("Candies, faster candies!", this.getFasterCandiesPrice.bind(this), this.fasterCandies.bind(this), "Congratulations! You will now gain more candies each second!", []);
+ this.addSpell("Candies, more candies!", this.getMoreCandiesPrice.bind(this), this.moreCandies.bind(this), "///", []);
+ this.addSpell("Sword, better sword!", this.getBetterSwordPrice.bind(this), this.betterSword.bind(this), "///", ["specialSword"]);
+
+ // We sort the list
+ this.sortListDependingOnPrice();
+ },
+
+ sortListDependingOnPrice : function(){
+ this.list.sort(this.priceSortFunction);
+ },
+
+ priceSortFunction : function(spellA, spellB){
+ var priceA = spellA.price();
+ var priceB = spellB.price();
+
+ if(priceA < priceB) return -1;
+ else if(priceB < priceA) return 1;
+ return 0;
+ },
+
+ getBetterSwordPrice : function(){
+ return Math.floor(Math.pow(sword.specialPower+1, 2.6)) * 10000;
+ },
+
+ getFasterCandiesPrice : function(){
+ return Math.pow(this.fasterCandiesFiboCurr, 2) * 10000;
+ },
+
+ addSpell : function(name, price, effect, speech, conditions){
+ this.list.push({name:name, price:price, effect:effect, speech:speech, conditions:conditions});
+ },
+
+ getMoreCandiesPrice : function(){
+ return 300000;
+ },
+
+ betterSword : function(){
+ sword.setSpecialPower(sword.specialPower + 1);
+ this.sortListDependingOnPrice();
+
+ // And we change the hut's speech by ourselves
+ switch(sword.name){
+ case "Sword of Life":
+ hut.setSpeech("Your Sword of Life will now drain more energy from your enemies.");
+ break;
+ case "Sword of Flames":
+ hut.setSpeech("Your Sword of Flames is now more powerful.")
+ break;
+ case "Sword of Summoning":
+ hut.setSpeech("You can now summon " + sword.summonList[sword.getIndexOfBetterToSummon()].name + "!");
+ break;
+ }
+ },
+
+ moreCandies : function(){
+ var nbr = Math.floor(candies.nbrTotal/20);
+
+ // We can't gain more candies than the price we pay for the spell !
+ if(nbr > 300000) nbr = 300000;
+
+ candies.setNbrOwned(candies.nbrOwned + nbr);
+ hut.setSpeech("Here's " + nbr + " candies for you!");
+ },
+
+ nextFasterCandiesFiboStep : function(){
+ this.setFasterCandiesFibo(this.fasterCandiesFiboCurr, this.fasterCandiesFiboPrev + this.fasterCandiesFiboCurr);
+ },
+
+ setFasterCandiesFibo : function(prev, curr){
+ // Set the new values
+ this.fasterCandiesFiboPrev = prev;
+ this.fasterCandiesFiboCurr = curr;
+
+ // Sort the spells list depending on their price, since the price of the faster candies spell just changed
+ this.sortListDependingOnPrice();
+ },
+
+ fasterCandies : function(){
+ // We change candies per second
+ candies.setCandiesPerSecond(this.fasterCandiesFiboCurr);
+
+ // We continue fibo
+ this.nextFasterCandiesFiboStep();
+ }
+
+};
diff --git a/static/candies/scripts/status.js b/static/candies/scripts/status.js
new file mode 100755
index 00000000..d2316860
--- /dev/null
+++ b/static/candies/scripts/status.js
@@ -0,0 +1,66 @@
+var status2 = {
+
+ getText : function(){
+ var statusLines = [];
+
+ var character = this.getLinesFromThingIndex(quest.getCharacterIndex());
+ if(quest.getCharacterIndex() + 1 < quest.things.length && quest.things[quest.getCharacterIndex() + 1].type != "none"){
+ statusLines.push(this.formatLines(character));
+ if(quest.things[quest.getCharacterIndex() + 1].type == "mob") // If it's a mob
+ statusLines.push(this.formatLines(["", "VERSUS", "", ""]));
+ if(quest.things[quest.getCharacterIndex() + 1].type == "ally") // If it's an ally
+ statusLines.push(this.formatLines(["", " WITH ", "", ""]));
+ statusLines.push(this.getLinesFromThingIndex(quest.getCharacterIndex() + 1));
+ }
+ else{
+ statusLines.push(character);
+ }
+
+ return this.formatStatusLines(statusLines);
+ },
+
+ formatLines : function(lines){
+ var max_len = 0;
+ for(var i = 0; i < lines.length; i++){
+ if(lines[i].length > max_len) max_len = lines[i].length;
+ }
+
+ for(var i = 0; i < lines.length; i++){
+ if(lines[i].length < max_len){
+ for(var j = lines[i].length; j < max_len; j++){
+ lines[i] += " ";
+ }
+ }
+ lines[i] += " | ";
+ }
+ return lines;
+ },
+
+ formatStatusLines : function(lines){
+ var text = "";
+ var stop = false;
+ var i = 0;
+ while(stop == false){
+ stop = true;
+ text += "\n";
+ for(var j = 0; j < lines.length; j++){
+ if(lines[j].length > i){
+ text += lines[j][i];
+ stop = false; // While we have something to add, we continue
+ }
+ }
+ i++;
+ }
+ return text;
+ },
+
+ getLinesFromThingIndex : function(i){
+ var lines = [];
+ lines.push(" " + quest.things[i].text);
+ lines.push("HP : " + quest.things[i].hp + "/" + quest.things[i].max_hp);
+ lines.push("Weapon : " + quest.things[i].weapon);
+ lines.push("\"" + quest.things[i].description + "\"");
+ return lines;
+ }
+
+};
diff --git a/static/candies/scripts/swamp.js b/static/candies/scripts/swamp.js
new file mode 100755
index 00000000..8d1ea166
--- /dev/null
+++ b/static/candies/scripts/swamp.js
@@ -0,0 +1,237 @@
+var swamp = {
+
+ // Variables
+ shown : false,
+ step : 0,
+
+ // Functions
+ updateOnPageFinalFrog : function(){
+ var text = "";
+ var answer_form = "\n\n ";
+ switch(this.step){
+ case 4:
+ text = speech.makeSpeechFromText("Hello. I'm The Frog. I can provide you candies, and lots of things. I know how much you love candies. But I feel alone in this swamp. I'd like to play with you before. If you answer my questions correctly, the sweetest sweets will be yours.", 29, "");
+ text += "\n\n";
+ break;
+ case 5:
+ text = speech.makeSpeechFromText("First question: do you _really_ love candies?", 29, "");
+ text += answer_form;
+ break;
+ case 6:
+ text = speech.makeSpeechFromText("Perfect. Here's 10 candies. Many more candies are waiting for you.", 29, "");
+ text += "\n\n";
+ break;
+ case 7:
+ text = speech.makeSpeechFromText("Second question: if A implies B and B implies C, and D implies A, and E implies D, what does A imply?", 29, "");
+ text += answer_form;
+ break;
+ case 8:
+ text = speech.makeSpeechFromText("Great. You seem to understand basic logic. Here's 100 candies.", 29, "");
+ text += "\n\n";
+ break;
+ case 9:
+ text = speech.makeSpeechFromText("Third question. Consider 10 days. If I give you 1 candy on the first day, and each other day I give you twice more candies than the previous one, how many candies will I give you on the day number 10?", 29, "");
+ text += answer_form;
+ break;
+ case 10:
+ text = speech.makeSpeechFromText("Exactly. Let's speed up the process: here's your 512 candies right now! Playing with you is so exciting! Next question is for 1000 candies.", 29, "");
+ text += "\n\n";
+ break;
+ case 11:
+ text = speech.makeSpeechFromText("Fourth question: if you could be whatever you want, what would you be?", 29, "");
+ text += answer_form;
+ break;
+ case 12:
+ text = speech.makeSpeechFromText("Correct! Everyone wants to be a frog. Here's your 1000 candies.", 29, "");
+ text += "\n\n";
+ break;
+ case 13:
+ text = speech.makeSpeechFromText("Here's a story: there's a fox, a lion and a wolf inside a lunar crater. The fox is about to bite the lion, which is about to bite the wolf, which is about to bite the fox. It's snowing and a shrub is watching the scene. Who's enjoying the story?", 29, "");
+ text += answer_form;
+ break;
+ case 14:
+ text = speech.makeSpeechFromText("Right, you were enjoying it! At least, I hope so. Here's a chocolate bar for you. It's very precious.", 29, "");
+ text += "\n\n";
+ break;
+ case 15:
+ text = speech.makeSpeechFromText("Now, just type the answer to that question and I'll give you a very special present: what is the only thing to go beyond the limits of our universe?", 29, "");
+ text += answer_form;
+ break;
+ case 16:
+ text = speech.makeSpeechFromText("Yes it is! Now, here's 5 very special potions. They'll be very useful during quests.", 29, "");
+ text += "\n\n";
+ break;
+ default:
+ text = speech.makeSpeechFromText("I have no more sweets to give you. It was a real pleasure to play with you. Thanks a lot.", 29, "");
+ break;
+ }
+
+ text += "\n\n";
+
+ htmlInteraction.setInnerHtml("map", "\
+ .--._.--.\n\
+ The ( O O ) Frog\n\
+ / . . \\\n\
+ .`._______.'.\n\
+ /( )\\\n\
+ _/ \\ \\ / / \\_\n\
+ .~ ` \\ \\ / / ' ~.\n\
+ { -. \\ V / .- }\n\
+_ _`. \\ | | | / .'_ _\n\
+>_ _} | | | {_ _<\n\
+ /. - ~ ,_-' .^. `-_, ~ - .\\\n\
+ '-'|/ \\|`-`\n\n\
+" + text);
+ },
+
+ updateOnPage : function(){
+ if(this.shown){
+
+ switch(this.step){
+ case 0:
+ htmlInteraction.setInnerHtml("map", "\
+While you walk through the swamp,\n\
+following your map...\
+");
+ this.step = 1;
+ window.setTimeout(this.updateOnPage.bind(this), 3500);
+ break;
+ case 1:
+ htmlInteraction.setInnerHtml("map", "\
+On the horizon, you see a\n\
+ 00 frog\n\
+ (--) coming...\n\
+ ( || )\n\
+ ^^~~^^\
+");
+ this.step = 2;
+ window.setTimeout(this.updateOnPage.bind(this), 3500);
+ break;
+ case 2:
+ htmlInteraction.setInnerHtml("map", "\
+It is coming_ _\n\
+ slowly (o)--(o)\n\
+ but /.______.\\\n\
+ surely, \\________/\n\
+ ./ \\.\n\
+ ( . , )\n\
+ \\ \\_\\\\//_/ /\n\
+ ~~ ~~ ~~\
+");
+ this.step = 3;
+ window.setTimeout(this.updateOnPage.bind(this), 3500);
+ break;
+ case 3:
+ htmlInteraction.setInnerHtml("map", "\
+ .-. .-.\n\
+ ( o )_( o )\n\
+ __ / '-' '-' \\ __ it is\n\
+ / / \" \\ \\ green.\n\
+ | \\ _____, / |\n\
+ \\ \\`-._______.-'/ /\n\
+ _.-` /\\) (/\\ `-._\n\
+(_ / / /.___.\\ \\ \\ _)\n\
+ (_.(_/ / (_ _) \\ \\_)._)\n\
+ (_(_)_) (_(_)_)\
+");
+ this.step = 4;
+ window.setTimeout(this.updateOnPage.bind(this), 3500);
+ break;
+ default:
+ this.updateOnPageFinalFrog();
+ break;
+ }
+
+ }
+ },
+
+ enter : function(){
+ objects.leave();
+
+ this.shown = true;
+
+ this.updateOnPage();
+ },
+
+ leave : function(){
+ this.shown = false;
+
+ htmlInteraction.setInnerHtml("map", "");
+ //buttons.enableHomeButtons();
+ },
+
+ resetComment : function(){
+ htmlInteraction.setInnerHtml("swamp_comment", "");
+ },
+
+ setComment : function(value){
+ htmlInteraction.setInnerHtml("swamp_comment", value);
+ window.setTimeout(this.resetComment.bind(this), 1000); // We set the timeout to reset it in one second
+ },
+
+ setStep : function(value){
+ // We change the value
+ this.step = value;
+
+ // If the swamp is shown
+ if(this.shown){
+ // We update on page
+ this.updateOnPage();
+ // We possibly focus
+ if(this.step >= 4 && this.step <= 16){
+ htmlInteraction.focusElement("answer");
+ }
+ }
+ },
+
+ answer : function(){
+ var ans = htmlInteraction.getElement("answer").value.toLowerCase().replace(/[^\w]|_/g, "");
+ htmlInteraction.getElement("answer").focus(); // Re focus after answering
+
+ switch(this.step){
+ case 5:
+ if(ans == "yes"){
+ candies.setNbrOwned(candies.nbrOwned + 10);
+ this.setStep(6);
+ }
+ else this.setComment("Wrong.");
+ break;
+ case 7:
+ if(ans == "c" || ans == "b" || ans == "candb" || ans == "bandc"){
+ candies.setNbrOwned(candies.nbrOwned + 100);
+ this.setStep(8);
+ }
+ else this.setComment("Wrong.");
+ break;
+ case 9:
+ if(ans == "512"){
+ candies.setNbrOwned(candies.nbrOwned + 512);
+ this.setStep(10);
+ }
+ else this.setComment("Wrong.");
+ break;
+ case 11:
+ if(ans == "frog" || ans == "afrog" || ans == "thefrog"){
+ candies.setNbrOwned(candies.nbrOwned + 1000);
+ this.setStep(12);
+ }
+ else this.setComment("Wrong.");
+ break;
+ case 13:
+ if(ans == "me"){
+ chocolateBars.setNbrOwned(chocolateBars.nbrOwned + 1);
+ this.setStep(14);
+ }
+ else this.setComment("Wrong.");
+ break;
+ case 15:
+ if(ans == "theanswertothatquestion" || ans == "theanswer" || ans == "answer" || ans == "answertothatquestion"){
+ potions.getPotions(potions.list.berserk, 5);
+ this.setStep(16);
+ }
+ else this.setComment("Wrong.");
+ break;
+ }
+ }
+
+}
diff --git a/static/candies/scripts/sword.js b/static/candies/scripts/sword.js
new file mode 100755
index 00000000..1210946b
--- /dev/null
+++ b/static/candies/scripts/sword.js
@@ -0,0 +1,494 @@
+var sword = {
+
+ // Variables
+ name : "none",
+ specialSword : false,
+ specialPower : 1, // How many the Sword of Life can steal hp, additional damage of the Sword of Flames...
+ // List of summoned things with the level we need to summon them
+ summonList : [],
+
+ // Functions
+
+ onload : function(){
+ this.summonList.push({name:"imps", summonFunction:quest.makeImp.bind(quest), powerNeeded:1});
+ this.summonList.push({name:"orcs", summonFunction:quest.makeOrc.bind(quest), powerNeeded:2});
+ this.summonList.push({name:"draugrs", summonFunction:quest.makeDraugr.bind(quest), powerNeeded:3});
+ this.summonList.push({name:"a chupacabra", summonFunction:quest.makeChupacabra.bind(quest), powerNeeded:4});
+ this.summonList.push({name:"a golem", summonFunction:quest.makeGolem.bind(quest), powerNeeded:5});
+ this.summonList.push({name:"a chimera", summonFunction:quest.makeChimera.bind(quest), powerNeeded:6});
+ this.summonList.push({name:"a candy monster", summonFunction:quest.makeCandyMonster.bind(quest), powerNeeded:7});
+ },
+
+ buyThisSword : function(name){
+ if(this.name != name){ // If we're not trying to buy the current sword
+ switch(name){
+ case "wooden sword":
+ if(candies.nbrOwned >= shop.currentSwordPrice){
+ candies.setNbrOwned(candies.nbrOwned - shop.currentSwordPrice);
+ shop.setMerchantSpeech("Great! This wooden sword isn't the best, for sure, but it really didn't cost so much.");
+ shop.hideProduct("sword");
+ }
+ else{
+ shop.setMerchantSpeech("You don't have enough candies. You should save up candies to buy it : swords are useful nowadays.");
+ return;
+ }
+ break;
+ case "copper sword":
+ if(candies.nbrOwned >= shop.currentSwordPrice){
+ candies.setNbrOwned(candies.nbrOwned - shop.currentSwordPrice);
+ shop.setMerchantSpeech("This copper sword is quite heavy, but it slays efficiently.");
+ shop.hideProduct("sword");
+ }
+ else{
+ shop.setMerchantSpeech("You need 300 candies to buy that sword! Did you know that copper slowly reacts with atmospheric oxygen forming a layer of brown-black copper oxide?");
+ return;
+ }
+ break;
+ case "iron sword":
+ if(candies.nbrOwned >= shop.currentSwordPrice){
+ candies.setNbrOwned(candies.nbrOwned - shop.currentSwordPrice);
+ shop.setMerchantSpeech("This iron sword could cut almost anything, if you're strong enough to use it.");
+ shop.hideProduct("sword");
+ }
+ else{
+ shop.setMerchantSpeech("You need more candies for the iron sword. Iron is strong. Iron is reliable. Iron will obey your slaying desire.");
+ return;
+ }
+ break;
+ case "silver sword":
+ if(candies.nbrOwned >= shop.currentSwordPrice){
+ candies.setNbrOwned(candies.nbrOwned - shop.currentSwordPrice);
+ shop.setMerchantSpeech("One thousand candies for meeee! Uh, I mean, this silver sword is even stronger than the iron one! You had to buy it.");
+ shop.hideProduct("sword");
+ }
+ else{
+ shop.setMerchantSpeech("One thousand candies for the silver sword! My marginal profit can't handle less than that.");
+ return;
+ }
+ break;
+ case "diamond sword":
+ if(candies.nbrOwned >= shop.currentSwordPrice){
+ candies.setNbrOwned(candies.nbrOwned - shop.currentSwordPrice);
+ shop.setMerchantSpeech("Diamond! This is the best sword I can sell you. It will cut rocks as if they were made of butter.");
+ shop.hideProduct("sword");
+ }
+ else{
+ shop.setMerchantSpeech("You need more candies. The diamond sword is quite expensive, but it's worth it!");
+ return;
+ }
+ break;
+ }
+ this.setName(name); // We bought it, since we didn't return : we change the name
+ }
+ },
+
+ enchantImpInvocation : function(){
+ if(potions.list.impInvocationScroll.nbrOwned > 0){
+ this.setSpecialSword(true);
+ this.setName("Sword of Summoning");
+ potions.list.impInvocationScroll.nbrOwned -= 1;
+ potions.updateOnPage();
+ forge.setStep(2);
+}
+ },
+
+ setSpecialSword : function(value){
+ this.specialSword = value;
+ },
+
+ setSpecialPower : function(value){
+ if(value > 0){
+ this.specialPower = value;
+ }
+ else this.specialPower = 0;
+ },
+
+ getIndexOfBetterToSummon : function(){
+ var indexOfBetterToSummon = 0;
+ // We iterate over the list
+ for(var i = 0; i < this.summonList.length; i++){
+ // If we can summon this one and it is better than the current betterToSummon
+ if(this.summonList[i].powerNeeded <= this.specialPower && this.summonList[i].powerNeeded > this.summonList[indexOfBetterToSummon].powerNeeded){
+ // This is now the better to summon
+ indexOfBetterToSummon = i;
+ }
+ }
+ return indexOfBetterToSummon;
+ },
+
+ summonHere : function(id){
+ // One chance out of two we summon something
+ if(random.flipACoin()){
+ // We summon the better to summon
+ quest.things[id] = this.summonList[this.getIndexOfBetterToSummon()].summonFunction();
+ }
+ },
+
+ enchantFire : function(){
+if(potions.list.fireScroll.nbrOwned > 0){
+ this.setSpecialSword(true);
+ this.setName("Sword of Flames");
+ potions.list.fireScroll.nbrOwned -= 1;
+ potions.updateOnPage();
+ forge.setStep(2);
+}
+ },
+
+ enchantHealth : function(){
+if(potions.list.health.nbrOwned > 0){
+ this.setSpecialSword(true);
+ this.setName("Sword of Life");
+ potions.list.health.nbrOwned -= 1;
+ potions.updateOnPage();
+ forge.setStep(2);
+}
+ },
+
+ sharpen : function(){
+ this.setName("sharp chocolate sword");
+ forge.setStep(1);
+ },
+
+ coat : function(){
+ if(chocolateBars.nbrOwned >= 1){
+ chocolateBars.setNbrOwned(chocolateBars.nbrOwned - 1);
+ this.setName("chocolate sword");
+ htmlInteraction.hideButton("coat");
+ }
+ },
+
+ encrust : function(){
+ if(candies.nbrOwned >= 101){
+ candies.setNbrOwned(candies.nbrOwned - 101);
+ this.setName("candy diamond sword");
+ htmlInteraction.hideButton("encrust");
+ }
+ },
+
+ polish : function(){
+ if(lollipops.nbrOwned >= 30){
+ lollipops.setNbrOwned(lollipops.nbrOwned - 30);
+ this.setName("polished candy diamond sword");
+ htmlInteraction.hideButton("polish");
+ }
+ },
+
+ setName : function(value){
+ // We change the value
+ this.name = value;
+
+ // We possibly show a new product in the shop depending on the new sword name
+ switch(this.name){
+ case "wooden sword": shop.showProduct("copper_sword"); break;
+ case "copper sword": shop.showProduct("iron_sword"); break;
+ case "iron sword": shop.showProduct("silver_sword"); break;
+ case "silver sword": shop.showProduct("diamond_sword"); break;
+ default: shop.showProduct("products_after_swords"); break;
+ }
+
+ // Other stuff
+ htmlInteraction.setInnerHtml("sword", "You currently have a " + this.name + ".");
+ quest.defineMood();
+ htmlInteraction.setElementVisibility("sword", true);
+ htmlInteraction.setElementVisibility("quest_form", true);
+ buttons.checkSword();
+ inventory.updateOnPage();
+ },
+
+ // Ascii art
+ asciiWoodenSwordWithButton : "\
+ .\n\
+ / \\\n\
+ | |\n\
+ | | \n\
+ | |\n\
+ | |\n\
+ `--8--\'\n\
+ 8\n\
+ 0",
+
+ asciiWoodenSwordWithoutButton : "Wooden sword\n\
+ .\n\
+ / \\\n\
+ | |\n\
+ | |\n\
+ | |\n\
+ | |\n\
+ `--8--\'\n\
+ 8\n\
+ 0",
+
+ asciiCopperSwordWithButton : "\
+ .\n\
+ /:\\\n\
+ |||\n\
+ ||| \n\
+ |||\n\
+ |||\n\
+ `--8--\'\n\
+ 8\n\
+ 0",
+
+ asciiCopperSwordWithoutButton : "Copper sword\n\
+ .\n\
+ /:\\\n\
+ |||\n\
+ |||\n\
+ |||\n\
+ |||\n\
+ `--8--\'\n\
+ 8\n\
+ 0",
+
+ asciiIronSwordWithButton : "\
+ /|\n\
+ |\\|\n\
+ |||\n\
+ ||| \n\
+ |||\n\
+ |||\n\
+ |||\n\
+ |||\n\
+ ~-[{o}]-~\n\
+ |/|\n\
+ |/|\n\
+ `0\'",
+
+ asciiIronSwordWithoutButton : "Iron sword\n\
+ /|\n\
+ |\\|\n\
+ |||\n\
+ |||\n\
+ |||\n\
+ |||\n\
+ |||\n\
+ |||\n\
+~-[{o}]-~\n\
+ |/|\n\
+ |/|\n\
+ `0\'",
+
+ asciiSilverSwordWithButton : "\
+ |\\\n\
+ |/|\n\
+ |||\n\
+ [|] \n\
+ |||\n\
+ [|]\n\
+ |||\n\
+ |||\n\
+ \\_[[O]]_/\n\
+ |/|\n\
+ |/|\n\
+ `0\'",
+
+ asciiSilverSwordWithoutButton : "Silver sword\n\n\
+ |\\\n\
+ |/|\n\
+ |||\n\
+ [|]\n\
+ |||\n\
+ [|]\n\
+ |||\n\
+ |||\n\
+ \\_[[O]]_/\n\
+ |/|\n\
+ |/|\n\
+ `0\'",
+
+ asciiDiamondSwordWithButton : "\
+ /|\n\
+ |;|\n\
+ |:|\n\
+ |;| \n\
+ |:|\n\
+ |;|\n\
+ |:|\n\
+ |;|\n\
+ |:|\n\
+ \\_[[C]]_/\n\
+ |N|\n\
+ |D|\n\
+ `0\'",
+
+ asciiDiamondSwordWithoutButton : "Diamond sword\n\n\
+ /|\n\
+ |;|\n\
+ |:|\n\
+ |;|\n\
+ |:|\n\
+ |;|\n\
+ |:|\n\
+ |;|\n\
+ |:|\n\
+ \\_[[C]]_/\n\
+ |N|\n\
+ |D|\n\
+ `0\'",
+
+ asciiCandyDiamondSword : "Candy diamond\nsword\n\n\
+ /|\n\
+ |o|\n\
+ |:|\n\
+ |o|\n\
+ |:|\n\
+ |o|\n\
+ |:|\n\
+ |o|\n\
+ o |:| o\n\
+ \\_[[C]]_/\n\
+ |N|\n\
+ |D|\n\
+ 'O'",
+
+ asciiPolishedCandyDiamondSword : "Polished candy\ndiamond sword\n\n\
+ /|\n\
+ |o|\n\
+ | |\n\
+ |o|\n\
+ | |\n\
+ |o|\n\
+ | |\n\
+ |o|\n\
+ o | | o\n\
+ \\_([-])_/\n\
+ | |\n\
+ | |\n\
+ 'O'",
+
+ asciiChocolateSword : "Chocolate sword\n\n\
+ /|\n\
+ |o|\n\
+ |~|\n\
+ |o|\n\
+ |~|\n\
+ |o|\n\
+ |~|\n\
+ |o|\n\
+ o |~| o\n\
+ \\~([-])~/\n\
+ |~|\n\
+ |~|\n\
+ 'O'",
+
+ asciiSharpChocolateSword : "Sharp chocolate\nsword\n\n\
+ /|\n\
+ |^|\n\
+ |~|\n\
+ |^|\n\
+ |~|\n\
+ |^|\n\
+ |~|\n\
+ |^|\n\
+ . |~| .\n\
+ \\~([-])~/\n\
+ |~|\n\
+ |~|\n\
+ 'O'",
+
+ asciiSwordOfFlames : "Sword of Flames\n\n\
+ _\n\
+ /#|\n\
+ |##|\n\
+ |##|\n\
+ |#F|\n\
+ |L#|\n\
+ |#A|\n\
+ |M#|\n\
+ |#E|\n\
+ |S#|\n\
+ |##|\n\
+ |##|\n\
+ _ |##| _\n\
+ \\\\-([--])-//\n\
+ |``|\n\
+ |``|\n\
+ |``|\n\
+ \"##\"",
+
+ asciiSwordOfLife : "Sword of Life\n\n\
+ _ _\n\
+ ( `\\/' )\n\
+ `\\ /'\n\
+ |\\/|\n\
+ | |\n\
+ |~ |\n\
+ | |\n\
+ | ~|\n\
+ | |\n\
+ | |\n\
+ | ~|\n\
+ |~ |\n\
+ | |\n\
+ | ~|\n\
+/~~([--])~~\\\n\
+ | |\n\
+ | |\n\
+ | |\n\
+ \"OO\"",
+
+ asciiSwordOfSummoning : "Sword of Summoning\n\n\
+ _\n\
+ /*| _\n\
+ |% | / \\\n\
+ | | /& /\n\
+ | &| / /\n\
+ | | / /\n\
+ |% | / %/\n\
+ | |/ /\n\
+ | * & /\n\
+ | /\n\
+ |& */\n\
+ | |\n\
+ |_%|\n\
+ ~~([__])~~\n\
+ |*%|\n\
+ |%&|\n\
+ |*&|\n\
+ \'42\'",
+
+ asciiSwordOfLiflamesummoning : "Sword of\nLiflamesummoning\n\n\
+ _ _\n\
+ ( `\\/' )\n\
+ `\\ /'\n\
+ |\\/| _\n\
+ |% | /#\\\n\
+ | | //\n\
+ | &| /##/\n\
+ | | /##/\n\
+ |% | /#%/\n\
+ | |/##/\n\
+ | * /\n\
+ | #/\n\
+ |& */\n\
+ | |\n\
+ |_%|\n\
+ ~~([__])~~\n\
+ |l%|\n\
+ |%f|\n\
+ |s%|\n\
+ \'42\'",
+
+ asciiSwordOfRandomness : " Sword of Randomness\n\n\
+ _ _\n\
+ À ( `\\/' )\n\
+ À `\\ e /'\n\
+ À À |\\/| _\n\
+ À |% | /#\\\n\
+ À qsd | | //\n\
+ | &| /##/\n\
+ ÀÀ| | /##/\n\
+ |% | /s%/\n\
+ f | |À/##/\n\
+ | $*À /\n\
+ r | #/\n\
+ |& */\n\
+ ù | |\n\
+ dfg |_%|\n\
+ ~~(É[__])~~\n\
+ |l%|\n\
+ A |%f|\n\
+ |s%sdd|\n\
+ \'42\'"
+
+};
diff --git a/static/candies/scripts/tabs.js b/static/candies/scripts/tabs.js
new file mode 100755
index 00000000..683a4775
--- /dev/null
+++ b/static/candies/scripts/tabs.js
@@ -0,0 +1,156 @@
+var tabs = {
+
+// Variables
+ length : 0, // Number of tabs
+ list : new Array(), // List of tabs buttons
+ active : 0, // Number of active tab
+ lastKeyPress : 0, // blbl
+
+// Functions
+
+ // Enable the tab ( display : inline on the tab )
+ enable : function(n){
+ if(this.list[n].enabled == false){
+ this.list[n].enabled = true;
+ this.list[n].button.css("display", "inline");
+ }
+ },
+
+ // Disable the tab ( display : none on the tab )
+ disable : function(n){
+ if(this.list[n].enabled == true){
+ this.list[n].enabled = false;
+ this.list[n].button.css("display", "none");
+ }
+ },
+
+ // Show the tab ( slideDown/show based on the animSlide variable )
+ show : function(n){
+ this.getTab(this.list[n].button).slideDown(200);
+ },
+
+ // Hide the tab ( slideUp/hide based on the animSlide variable )
+ hide : function(n){
+ if(n == 1){ // If we're hiding the inventory tab, we try to leave all the maps
+ objects.leave();
+ }
+
+ this.getTab(this.list[n].button).slideUp(200);
+ },
+
+ // Select the tab
+ select : function(something){
+ // Remove the class "active" on the last active tab
+ this.list[this.active].button.removeClass("active");
+
+ // Get the new active tab
+ this.active = something;
+
+ // For all tabs
+ for(var i = 0; i < this.length; i++){
+ // If the tab is the new active tab
+ if(i == this.active){
+ // Add the class "active" on the new active tab
+ this.list[i].button.addClass("active");
+ // Show that tab
+ this.show(i);
+ }
+ // Else, hide that tab
+ else
+ this.hide(i);
+ }
+ },
+
+ // Next tab
+ next : function(){
+ var nextI = this.active;
+
+ for(var i = 0; i < this.length; i++){
+ // We search the nextI
+ nextI += 1;
+ if(nextI == this.length)
+ nextI = 0;
+ // We select the next tab if possible
+ if(this.list[nextI].enabled){
+ this.select(nextI);
+ break;
+ }
+ }
+ },
+
+ // Prev tab
+ prev : function() {
+ var prevI = this.active;
+
+ for(var i = this.length; i > 0; i--){
+ // We search the nextI
+ prevI -= 1;
+ if(prevI == -1)
+ prevI = this.length-1;
+ // We select the next tab if possible
+ if(this.list[prevI].enabled){
+ this.select(prevI);
+ break;
+ }
+ }
+ },
+
+ // Get the tab attribute
+ getTab : function(something){
+ return $("#"+something.attr("tab"));
+ },
+
+ bindKey : function(){
+ $("body").keydown( function(e) {
+ var currentTime = new Date().getTime();
+
+ // Tabs keys
+ if(currentTime - tabs.lastKeyPress > 50) {
+ if(e.which == 39)
+ tabs.next();
+ else if(e.which == 37)
+ tabs.prev();
+ /*else
+ alert("Code for Key Pressed : " + e.which);*/
+
+ tabs.lastKeyPress = currentTime;
+ }
+
+ // Quest keys
+ if(e.which == 73){
+ hell.goUp();
+ }
+ else if(e.which == 75){
+ hell.goDown();
+ }
+
+ if(e.which == developperComputer.letter){
+ developperComputer.useLetter();
+ }
+
+ });
+ },
+
+ //On Load
+ onload : function(){
+ // Get the number of tabs
+ this.length = $("#tabs button").length;
+
+ // Generate the list of tabs buttons
+ for(var i = 0; i < this.length; i++){
+ this.list.push({button:$(".tab-" + i), enabled:true});
+ this.disable(i);
+ }
+
+ // Select the first tab
+ this.select(0);
+
+ // Bind click event on all tabs to do select(that tab)
+ for(var i = 0; i < this.length; i++){
+ this.list[i].button.bind('click', tabs.select.bind(tabs, i));
+ }
+
+ // Bind key
+ this.bindKey();
+ }
+};
diff --git a/static/candies/scripts/underwaterCave.js b/static/candies/scripts/underwaterCave.js
new file mode 100755
index 00000000..d0fe0ade
--- /dev/null
+++ b/static/candies/scripts/underwaterCave.js
@@ -0,0 +1,255 @@
+var underwaterCave = {
+
+ // Variables
+ size : 54,
+
+ // Functions
+ onload : function(){
+ land.addLand("Underwater cave", this.size, 2, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ move : function(){
+ var defeated = false;
+ if(quest.things[51].type != "mob") defeated = true; // The Whale has been defeated
+
+ // We create a variable to store the lines of the underwater cave, depending on if the Whale is defeated or not
+ var lines = [];
+ if(defeated == false) lines = this.text.slice(0);
+ else lines = this.textWithoutWhale.slice(0);
+
+ // We make bubbles go up
+ for(var i = this.bubbles.length - 1; i >= 0; i--){
+ if(this.bubbles[i].y == 0 || lines[this.bubbles[i].y-1].charAt(this.bubbles[i].x) != " "){
+ this.bubbles.splice(i, 1);
+ }
+ else this.bubbles[i].y -= 1;
+ }
+
+ // We add bubbles if there isn't enough
+ if(this.bubbles.length < 4){
+ var b = this.bubblesStartingPositions[random.getRandomIntUpTo(this.bubblesStartingPositions.length-1)];
+ if(lines[b.y].charAt(b.x) == " " && lines[b.y-1].charAt(b.x) == " "){
+ this.bubbles.push({x:0, y:0});
+ this.bubbles[this.bubbles.length-1].x = b.x;
+ this.bubbles[this.bubbles.length-1].y = b.y;
+ }
+ }
+ },
+
+ load : function(){
+ for(var i = 1; i < quest.things.length; i++){
+ if(i < 47){ // If we're before the place of octopus guardians
+ if(i > 2){ // If we're underwater
+ if(i >= 26 && i <= 35){ // Eel zone
+ if(random.oneChanceOutOf(3)){
+ quest.things[i] = land.createMob("EEL", 3, 3, "electric tail", "An eel. Weak, but aggressive.", [drops.createDrop("candies", 50 + random.getRandomIntUpTo(50))]);
+ }
+ }
+ else{
+ if(random.flipACoin()){
+ var n = 9 + random.getRandomIntUpTo(3);
+ quest.things[i] = land.createMob("F~H", n, n, "fins", "A fish. Easy to beat.", [drops.createDrop("candies", 5)]);
+ }
+ }
+ }
+ }
+ else if(i <= 50){ // If we're before the whale
+ if(random.getRandomIntUpTo(10) <= 9) // 9/10 chances
+ quest.things[i] = land.createMob("OCT", 45, 45, "tentacles", "An octopus guardian. It looks dangerous.", []);
+ }
+ else if(i == 51){ // It's the whale (52 and 53 must be void)
+ quest.things[i] = land.createMob("The Whale.", 100, 100, "giant tail", "The Whale does not like to be disturbed.", [drops.createDrop("candies", 400 + random.getRandomIntUpTo(400)), drops.createDrop("object", "key", true), drops.createDrop("object", "hutMap", true), drops.createDrop("object", "swampMap", true), drops.createDrop("object", "boots", true), drops.createDrop("object", "wellMap", true), drops.createDrop("object", "magicianHat", true), drops.createDrop("object", "pinkRing", true), drops.createDrop("object", "forgeMap", true)]);
+ }
+ }
+ },
+
+ getText : function(){
+ var defeated = false;
+ if(quest.things[51].type != "mob") defeated = true; // The Whale has been defeated
+
+ // We create a variable to store the lines of the underwater cave, depending on if the Whale is defeated or not
+ var lines = [];
+ if(defeated == false) lines = this.text.slice(0);
+ else lines = this.textWithoutWhale.slice(0);
+
+ // We modify this variable by adding things to it
+ for(var i = 0; i < this.size; i++){
+ if(defeated == true || (defeated == false && i <= 50)){ // If we defeated the Whale or we're not drawing the things located after the Whale
+ if(quest.things[i].type != "none"){
+ lines[this.positions[i].y] = lines[this.positions[i].y].replaceAt(this.positions[i].x, quest.things[i].text);
+ }
+ }
+ }
+
+ // We modify this land var by drawing bubbles
+ for(var i = this.bubbles.length - 1; i >= 0; i--){
+ if(lines[this.bubbles[i].y].charAt(this.bubbles[i].x) == " ") lines[this.bubbles[i].y] = lines[this.bubbles[i].y].replaceAt_with_size(this.bubbles[i].x, "°", 1);
+ else this.bubbles.splice(i, 1);
+ }
+
+ return lines.join("");
+ },
+
+ // Variables
+
+ text : [
+ " / . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+ "___________| . . . . . . . . . . . . . . . . . . . . . . _______ . . .\n",
+ ". . .| |. . . . . . . . . . . . . . . . . . . ._____/ \\ . . .\n",
+ " . . | | . . . ________. . . . . . . . . . . ./ \\ . .\n",
+ ". . .| \\_____/ \\_______ . . . . . . ./ \\ . .\n",
+ " . . \\ \\____________/ \\ .\n",
+ ". . . \\ __ | .\n",
+ " . . . \\ __/. | |.\n",
+ ". . . . \\ ________/. . .| | .\n",
+ " . . . . \\ ____/. . . . . . ./ / .\n",
+ ". . . . . \\___ __/. . . . . . . . ./ / . .\n",
+ " . . . . . . .\\ ______/. . . . . . . . . ./ / . .\n",
+ ". . . . . . . .\\_____________/. . . . . ____. . . . . ./ / . . .\n",
+ " . .__________ . . . . . . . . . . . __/ \\_________/ \\. . .\n",
+ ". ./ \\ . . . . . . . ______/ \\. . .\n",
+ " ./ ::. \\_____________/ |. .\n",
+ ".|(\\./) .-\"\"-. | . .\n",
+ " | `\\'-'` \\ / . .\n",
+ ".| '.___,_`__/ / . . .\n",
+ " | __________ _____________/ . . .\n",
+ ". \\_____ ________/ . . . . .\\_________/. . . . . . . . . . .\n",
+ " . . . .\\__________/ . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+ ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."
+ ],
+
+ textWithoutWhale : [
+ " / . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+ "___________| . . . . . . . . . . . . . . . . . . . . . . _______ . . .\n",
+ ". . .| |. . . . . . . . . . . . . . . . . . . ._____/ \\ . . .\n",
+ " . . | | . . . ________. . . . . . . . . . . ./ \\ . .\n",
+ ". . .| \\_____/ \\_______ . . . . . . ./ \\ . .\n",
+ " . . \\ \\____________/ \\ .\n",
+ ". . . \\ __ | .\n",
+ " . . . \\ __/. | |.\n",
+ ". . . . \\ ________/. . .| | .\n",
+ " . . . . \\ ____/. . . . . . ./ / .\n",
+ ". . . . . \\___ __/. . . . . . . . ./ / . .\n",
+ " . . . . . . .\\ ______/. . . . . . . . . ./ / . .\n",
+ ". . . . . . . .\\_____________/. . . . . ____. . . . . ./ / . . .\n",
+ " . .__________ . . . . . . . . . . . __/ \\_________/ \\. . .\n",
+ ". ./ \\ . . . . . . . ______/ \\. . .\n",
+ " ./ \\_____________/ |. .\n",
+ ".| | . .\n",
+ " | / . .\n",
+ ".| / . . .\n",
+ " | __________ _____________/ . . .\n",
+ ". \\_____ ________/ . . . . .\\_________/. . . . . . . . . . .\n",
+ " . . . .\\__________/ . . . . . . . . . . . . . . . . . . . . . . . . .\n",
+ ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."
+ ],
+
+ positions : [
+ {x:0, y:1},
+ {x:3, y:1},
+ {x:6, y:1},
+ {x:7, y:2},
+ {x:7, y:3},
+ {x:7, y:4},
+ {x:9, y:5},
+ {x:11, y:6},
+ {x:13, y:7},
+ {x:14, y:8},
+ {x:15, y:9},
+ {x:18, y:10},
+ {x:21, y:10},
+ {x:24, y:9},
+ {x:27, y:8},
+ {x:30, y:7},
+ {x:33, y:7},
+ {x:36, y:8},
+ {x:39, y:8},
+ {x:42, y:7},
+ {x:45, y:7},
+ {x:48, y:7},
+ {x:51, y:6},
+ {x:54, y:5},
+ {x:57, y:4},
+ {x:60, y:5},
+ {x:62, y:6},
+ {x:62, y:7},
+ {x:62, y:8},
+ {x:61, y:9},
+ {x:60, y:10},
+ {x:59, y:11},
+ {x:58, y:12},
+ {x:58, y:13},
+ {x:58, y:14},
+ {x:58, y:15},
+ {x:55, y:16},
+ {x:52, y:17},
+ {x:51, y:18},
+ {x:48, y:18},
+ {x:45, y:19},
+ {x:42, y:19},
+ {x:39, y:18},
+ {x:36, y:17},
+ {x:33, y:16},
+ {x:30, y:17},
+ {x:27, y:17},
+ {x:25, y:18},
+ {x:22, y:18},
+ {x:19, y:18},
+ {x:16, y:18},
+ {x:13, y:18},
+ {x:10, y:18},
+ {x:7, y:18}
+ ],
+
+ bubblesStartingPositions : [
+ {x:10, y:9},
+ {x:13, y:9},
+ {x:18, y:11},
+ {x:20, y:11},
+ {x:22, y:11},
+ {x:24, y:11},
+ {x:26, y:11},
+ {x:30, y:10},
+ {x:32, y:10},
+ {x:34, y:10},
+ {x:38, y:9},
+ {x:41, y:8},
+ {x:43, y:8},
+ {x:54, y:7},
+ {x:56, y:7},
+ {x:57, y:5},
+ {x:59, y:5},
+ {x:63, y:18},
+ {x:61, y:18},
+ {x:59, y:18},
+ {x:57, y:18},
+ {x:55, y:18},
+ {x:53, y:18},
+ {x:51, y:18},
+ {x:49, y:19},
+ {x:47, y:19},
+ {x:45, y:19},
+ {x:43, y:19},
+ {x:41, y:19},
+ {x:38, y:18},
+ {x:36, y:18},
+ {x:34, y:18},
+ {x:32, y:18},
+ {x:30, y:18},
+ {x:27, y:19},
+ {x:25, y:19},
+ {x:23, y:19},
+ {x:21, y:19},
+ {x:18, y:20},
+ {x:16, y:20},
+ {x:14, y:20},
+ {x:12, y:20},
+ {x:10, y:20},
+ {x:7, y:19},
+ {x:5, y:19},
+ {x:3, y:19}
+ ],
+
+ bubbles : []
+
+};
diff --git a/static/candies/scripts/wishingWell.js b/static/candies/scripts/wishingWell.js
new file mode 100755
index 00000000..8c900642
--- /dev/null
+++ b/static/candies/scripts/wishingWell.js
@@ -0,0 +1,155 @@
+var wishingWell = {
+
+ // Variables
+ shown : false,
+ speech : "",
+ step : 0,
+
+ // Functions
+ updateOnPage : function(){
+ var text = "";
+
+ // Well drawing
+ text += "\
+ .-------------.\n\
+ /= ^ =_ ^-_- = \\\n\
+ /^ ==_ -_ = _ ^ \\\n\
+ / =_ ^ -_ = _ = \\\n\
+/_=_^___=_-^__=___=_^_\\\n\
+ __||____ ___ ____||_\n\
+ `=||====//_\\\\====||=|_\n\
+ || |===| || \'-\'\n\
+ ||_..-|___|-.._||\n\
+ |\'-,._______..-\'|\n\
+ ||__ | __] __]_|\n\
+ |_| ]__|__ _| __|\n\
+ |__[ _ ]_ __[_ |\n\
+ |_| _ |_ ]_ _[_ |\n\
+ `\"-..........--\"`\n\
+"
+
+ // Buttons & speech drawing
+ switch(this.step){
+ case 0:
+ // Button
+ text += "\n\n";
+ break;
+ case 1:
+ // Speech
+ text += "\n";
+ text += speech.makeSpeechFromText(this.speech, 23, "");
+
+ // Buttons
+ text += "\n\n";
+ text += "\n";
+ text += "\n";
+ break;
+ case 2:
+ // Speech
+ text += "\n";
+ text += speech.makeSpeechFromText(this.speech, 23, "");
+ break;
+ }
+
+ text += "\n\n";
+
+ htmlInteraction.setInnerHtml("map", text);
+ },
+
+ potionsAndScrolls : function(){
+ var rand, total = 0;
+
+ // Potions
+ rand = 5 + random.getRandomIntUpTo(10);
+ potions.getPotions(potions.list.health, rand);
+ total += rand;
+
+ rand = 5 + random.getRandomIntUpTo(10);
+ potions.getPotions(potions.list.escape, rand);
+ total += rand;
+
+ rand = 3 + random.getRandomIntUpTo(3);
+ potions.getPotions(potions.list.berserk, rand);
+ total += rand;
+
+ rand = 5 + random.getRandomIntUpTo(5);
+ potions.getPotions(potions.list.superman, rand);
+ total += rand;
+
+ potions.getPotions(potions.list.cloning, 1);
+ total += 1;
+
+ // Scrolls
+ rand = 5 + random.getRandomIntUpTo(10);
+ potions.getPotions(potions.list.fireScroll, rand);
+ total += rand;
+
+ rand = 5 + random.getRandomIntUpTo(10);
+ potions.getPotions(potions.list.acidRainScroll, rand);
+ total += rand;
+
+ rand = 5 + random.getRandomIntUpTo(10);
+ potions.getPotions(potions.list.teleportScroll, rand);
+ total += rand;
+
+ rand = 3 + random.getRandomIntUpTo(3);
+ potions.getPotions(potions.list.earthquakeScroll, rand);
+ total += rand;
+
+ rand = 3 + random.getRandomIntUpTo(3);
+ potions.getPotions(potions.list.impInvocationScroll, rand);
+ total += rand;
+
+ // Usual stuff
+ this.setStep(2);
+ this.setSpeech("Here's " + total + " various potions and scrolls for you!");
+ this.updateOnPage();
+ },
+
+ candiesBy5 : function(){
+ candies.setNbrOwned(candies.nbrOwned * 5);
+ this.setStep(2);
+ this.setSpeech("Multiplicatus, multiplicata, multiplicatum! Your candies are now multiplied!");
+ this.updateOnPage();
+ },
+
+ lollipopsBy8 : function(){
+ lollipops.setNbrOwned(lollipops.nbrOwned * 8);
+ this.setStep(2);
+ this.setSpeech("Multiplicatus, multiplicata, multiplicatum! Your lollipops are now multiplied!");
+ this.updateOnPage();
+ },
+
+ throwCandy : function(){
+ candies.setNbrOwned(candies.nbrOwned - 1);
+ this.setStep(1);
+ this.setSpeech("I will grant you one wish! So choose carefully from the list below.");
+ this.updateOnPage();
+ },
+
+ setStep : function(value){
+ this.step = value;
+ },
+
+ setSpeech : function(value){
+ this.speech = value;
+ },
+
+ enter : function(){
+ objects.leave();
+
+ this.shown = true;
+
+ this.updateOnPage();
+
+ buttons.checkWishingWell();
+ },
+
+ leave : function(){
+ this.shown = false;
+
+ htmlInteraction.setInnerHtml("map", "");
+ //buttons.enableHomeButtons();
+ }
+
+};
diff --git a/static/candies/scripts/yourself.js b/static/candies/scripts/yourself.js
new file mode 100755
index 00000000..a7f11919
--- /dev/null
+++ b/static/candies/scripts/yourself.js
@@ -0,0 +1,59 @@
+var yourself = {
+
+ // Variables
+ size : 2,
+ canSurpass : false,
+ end : false,
+
+ // Functions
+ onload : function(){
+ land.addLand("Yourself", this.size, 7, this.load.bind(this), this.getText.bind(this), this.move.bind(this));
+ },
+
+ move : function(){
+ if(quest.things[0].type == "character" && quest.things[1].type == "mob"){
+ if(this.end == false){
+ quest.things[1].max_hp = quest.things[0].max_hp;
+ quest.things[1].hp = quest.things[0].hp;
+ }
+ else{
+ quest.things[1].hp = 0;
+ }
+ }
+ },
+
+ setCanSurpass : function(value){
+ this.canSurpass = value;
+ },
+
+ load : function(){
+ quest.things[1] = this.makeYourself();
+ this.end = false;
+ },
+
+ getText : function(){
+ // Create the text
+ var text = "";
+
+ if(quest.things[0].type == "character" && quest.things[1].type == "mob"){
+ text += quest.things[0].text;
+ text += quest.things[0].text;
+ }
+ else{
+ for(var i = 0; i < this.size; i++){
+ text += quest.things[i].text;
+ }
+ }
+
+ text +="";
+
+ return text;
+ },
+
+ makeYourself : function(){
+ var index = quest.getCharacterIndex();
+
+ return land.createMob("\\o/", quest.things[index].hp, quest.things[index].max_hp, sword.name, "You", []);
+ }
+
+};
diff --git a/static/jarvis.asc b/static/jarvis.asc
new file mode 100644
index 00000000..740c9393
--- /dev/null
+++ b/static/jarvis.asc
@@ -0,0 +1,52 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBFkUgS0BEAC1L4XyrokbSXv7oYRMRclX3G0VMmpY8otC6N4I4YeQp4iioHPO
+9iQny3LM/cBwHhGgD/GU1Ia5OGWZidjxNJGcOkfU8qajjqA8ObMGTm6zk5EYP+oV
+HBF/7q+6n1Qk7TiBcivo01JEhGczBd9HG6cQz4AsAzLjC/38CJyoniZgZqwxnPqM
+OWDF2KmfEddcPzRlIiNXPl2bddeNjqRoFptoamBIpfNPazkjPbufC+PgofBRQ6kv
+dU4PIBvlFijLOdopSTzjZNObBBKPtF2FHJIVOwvIfiEBPrbT2ugy4fo+r5ql8vE/
+aXDaWIuib9uO6t6w3iLYZ7xF8dCoC4mKuxMc/zRGWg7ecadoxEK68dT2AzRjUl64
+HNNJNEXZQwph6y8yqs8SENmsmmN7x/6q+kptIaafZBKs9/FkO3Gh74030/p93yrN
+dPSZhxhdyycNszJxk2uTg/Td3IK3LqH/L8GAIZg/B+Jsov+UX53qGBEz2awYIXt1
+/Auqd8Wlpm6GAM9R1I6KTz5iOL6luxvwyKb7qtuvMifCLx1c9zPgxMWSdXZ7TrOe
+Jw7YfRJU+JLNQ2G5lJdvWS1O+7TAnf7y4p7t4jAzEhmor0V5vg7ht6jH+0wEL7lH
+A2x1F+z6/yeimZsrcydKl9Wl3tSGyDYwI1ioES8gHmprlQ67zbJAGsLG1QARAQAB
+tCJKYWtlIEphcnZpcyA8amFrZWphcnZpc0BnbWFpbC5jb20+iQJOBBMBCAA4FiEE
+h/tLYAbdG+s+1H+r02y2b0ACslsFAlkUgS0CGwMFCwkIBwIGFQgJCgsCBBYCAwEC
+HgECF4AACgkQ02y2b0ACsls4WBAAkuG07Gi9wnvJL0MppRJfEM2iv3PLh7VYosID
+v4ekeJdFQxy9PO1OFwNZS4rq22tOLejOPDnaKkcgKX8P67SVttYmllo7aeHkkPcx
+RBZ/30Ik2D4LVREcBFB/6Q2or+ylxgbPQikrOdcIpRf0c66Zi2SbOZUao+wpF+gx
+M/0d0ChMysHYYN61cv7WKnGDMHLXH7L57MkE6UnJZNPLal/xQaZ/XWLW7DsYZbwp
+ZgqXC8QEeH+WMTIwFiNUnhR5pWP5R67YGMUi+khLnqFO7KSYs7N17+iF2b6NPtUE
+q9ZKPwww0dKEHA/X0p8OSXXoxp4wpStkp23I2rTeW8P7UZYjmjrnqLYsktKYqakc
+O7eOWrcmnkK8tHOcVdaqPfVebZHpkQXfq4fR48MXVZOmEpLESXP969j4zq7w51eP
+w9VRZwk0UhZxddkxwnNCN4019RwvsknNhw7IPJdc/iKeG6FpQqEOXZx0mDS0jbUm
+ipnRcCWmEfE9GHtRTUEA44uKAS5v1t/LeBVRmMlgo+wYczrSvTDA3GLaTRf8Un+p
+afowmBiplDqIeJyjlsVWOi895RXvQWOxAbESdQewIIsRSAjT8DvrkmRk2sGWgntC
+d5oC0Vra9zY+LzzjkrSchon12CQ9I2aBaemlGmb0yWJTcsa0Guut//LkjvyacMZL
+iZZbC0q5Ag0EWRSBLQEQAPUCnQ15WhKwGD1aZx/YrPHbgxWoPnXVR1+hXkVdQJqL
+aRmCxzdUWAUeF2E3tla4+5PAK7EChFB+o1lOz44HlzJ1j3TksJ1Fi4KsVFmx+nCR
+i5Ipeq7/0mqczRgoZgtbeQSP/WC79BPYM3Ki7CjmbQFrnoyvAdN/QS8kW8PPz2jv
+EoHkZKSqwjialFdfZY6iFDNtStz86hXCQ2O31QbMzNYEmhZLp7B2XKsOb6OmpTeY
+rV3CJhu66Eopp/U+g/vPWdrciVS2ASpJd4QDfyuvVQtV0HbAh3MB06FkH1xo6EB5
+NU6IDWqiYIeLP1GjTZYM0lZsrgEInFgiAJA4bQsZSw514du7hMno8jaMI+erHl9v
+5WlBWis/Dn39hVfP9vxT6ClQ5UxD8OjhMX+MlSqAKxZ9AkG2TurUbAhXesRCoYxe
+nBdbuLuWpSwm2JD/HYFZ/KPhZ57ejlnziKhFC2qIVYwO3TuG7Km7oesgbGiRaBTp
+FY0LMIS+cJpmEC6LAP3Zr2te4VTK4YyN2+wK6ASC/k6GbHlFUpFxhek+aNkY5OT/
+9R07BIKzCNhXBNtzwXvVE/jdMAar9Gr8CSMPYrX8wXrFED9oN6XNci4oItA79805
+FEYdpBPMI8MgEdKMwTQifBj6CYrx58Ssg6ZxEu5znf2rSmD8NhtsVVJNtLulKRml
+ABEBAAGJAjYEGAEIACAWIQSH+0tgBt0b6z7Uf6vTbLZvQAKyWwUCWRSBLQIbDAAK
+CRDTbLZvQAKyW3KRD/4sIO4rUg9ylk2aeFdZFw4pJUXA2d3PdIIuk4XT+AXlT3j3
+tEsUS3nKA8RxIoR2jvEgn2mDnZwEikVuK1aUI9nn8JvlxIoh0xd97FzwqO+6b79I
++Q8/GErwy+YhI422sND29qlMKBiQ1/1bg1zqBGl8+3OYj+Xyw+KzNHkOOBF4m9vV
+hAUvZONlQd8CWre5jBU7tYS7/g2w/otdSqZe6Ayamlxaoq0jTH4f4kwg6kOz8y6Z
+66RqMj2/U4/+0qhFszkX/FaQKQyLESrNrNe/IwFu+o+e+ocx9anuwTU26BRXMt0M
+LaxdKtWa+dFSm2PzTjoHZYqnuLa4ZO71t9comB+p0CHshAvt5hBoRqc069sVahkk
+kecXaSVHTc3t9UnOJvP3kYCiO0QGFIn9PD+v7oc21yAw9mawVEZgTNCSJnra6oNl
+nQ/+FDYVlw686BMZlzpDyC6nJbz/0EWxmMaWLSQWM8l9C1xX+EhM4tJmKP60aqRi
+QtGYwx45xjQXPZG4Eck0ft9UOM2/03lSsPvasJbYF32ZOhqAjCpNMcQJJD9Dn19R
+CabQeBS5ZZj27oWP0uzCL39wfYuT+qQ68wJ/87N/ocV8g8Gta+HXFg64Lfu3oYHQ
+IKHh0SFrOjES4emAyvcxt8VwwR2qD/iSJJ5nMwAfdOznVvDAfINk4NT64apR2A==
+=FOdm
+-----END PGP PUBLIC KEY BLOCK-----
+
diff --git a/static/robots.txt b/static/robots.txt
index fa7db9d2..49b7452a 100644
--- a/static/robots.txt
+++ b/static/robots.txt
@@ -1,5 +1,7 @@
User-Agent: *
+Disallow: /stuff/
Disallow: /y2k/
Disallow: /comp20/
Disallow: /scrabble/
+Disallow: /candies/
Disallow: /awesome/
diff --git a/static/stuff/An eyewitness account.pdf b/static/stuff/An eyewitness account.pdf
new file mode 100755
index 00000000..436f015c
Binary files /dev/null and b/static/stuff/An eyewitness account.pdf differ